Mutex Klass

Definition

En synkroniseringsprimerare som också kan användas för synkronisering mellan processer.

public ref class Mutex sealed : System::Threading::WaitHandle
public sealed class Mutex : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Mutex : System.Threading.WaitHandle
type Mutex = class
    inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(true)>]
type Mutex = class
    inherit WaitHandle
Public NotInheritable Class Mutex
Inherits WaitHandle
Arv
Arv
Attribut

Exempel

Det här exemplet visar hur ett lokalt Mutex objekt används för att synkronisera åtkomst till en skyddad resurs. Eftersom varje anropstråd blockeras tills den hämtar ägarskapet för mutexen måste den ReleaseMutex anropa metoden för att frigöra ägarskapet för mutex.

using System;
using System.Threading;

class Example
{
    // Create a new Mutex. The creating thread does not own the mutex.
    private static Mutex mut = new Mutex();
    private const int numIterations = 1;
    private const int numThreads = 3;

    static void Main()
    {
        // Create the threads that will use the protected resource.
        for(int i = 0; i < numThreads; i++)
        {
            Thread newThread = new Thread(new ThreadStart(ThreadProc));
            newThread.Name = String.Format("Thread{0}", i + 1);
            newThread.Start();
        }

        // The main thread exits, but the application continues to
        // run until all foreground threads have exited.
    }

    private static void ThreadProc()
    {
        for(int i = 0; i < numIterations; i++)
        {
            UseResource();
        }
    }

    // This method represents a resource that must be synchronized
    // so that only one thread at a time can enter.
    private static void UseResource()
    {
        // Wait until it is safe to enter.
        Console.WriteLine("{0} is requesting the mutex", 
                          Thread.CurrentThread.Name);
        mut.WaitOne();

        Console.WriteLine("{0} has entered the protected area", 
                          Thread.CurrentThread.Name);

        // Place code to access non-reentrant resources here.

        // Simulate some work.
        Thread.Sleep(500);

        Console.WriteLine("{0} is leaving the protected area", 
            Thread.CurrentThread.Name);

        // Release the Mutex.
        mut.ReleaseMutex();
        Console.WriteLine("{0} has released the mutex", 
            Thread.CurrentThread.Name);
    }
}
// The example displays output like the following:
//       Thread1 is requesting the mutex
//       Thread2 is requesting the mutex
//       Thread1 has entered the protected area
//       Thread3 is requesting the mutex
//       Thread1 is leaving the protected area
//       Thread1 has released the mutex
//       Thread3 has entered the protected area
//       Thread3 is leaving the protected area
//       Thread3 has released the mutex
//       Thread2 has entered the protected area
//       Thread2 is leaving the protected area
//       Thread2 has released the mutex
Imports System.Threading

Module Example
   ' Create a new Mutex. The creating thread does not own the mutex.
   Private mut As New Mutex()
   Private Const numIterations As Integer = 1
   Private Const numThreads As Integer = 3
   
   Public Sub Main()
        ' Create the threads that will use the protected resource.
        For i As Integer = 0 To numThreads - 1
            Dim newThread As New Thread(AddressOf ThreadProc)
            newThread.Name = String.Format("Thread{0}", i + 1)
            newThread.Start()
        Next

        ' The main thread exits, but the application continues to
        ' run until all foreground threads have exited.
    End Sub

    Private Sub ThreadProc()
        For i As Integer = 0 To numIterations - 1
            UseResource()
        Next
    End Sub

    ' This method represents a resource that must be synchronized
    ' so that only one thread at a time can enter.
    Private Sub UseResource()
        ' Wait until it is safe to enter.
        Console.WriteLine("{0} is requesting the mutex", 
                          Thread.CurrentThread.Name)
        mut.WaitOne()

        Console.WriteLine("{0} has entered the protected area", 
                          Thread.CurrentThread.Name)

        ' Place code to access non-reentrant resources here.

        ' Simulate some work.
        Thread.Sleep(500)

        Console.WriteLine("{0} is leaving the protected area", 
            Thread.CurrentThread.Name)

        ' Release the Mutex.
        mut.ReleaseMutex()
        Console.WriteLine("{0} has released the mutex", 
            Thread.CurrentThread.Name)
   End Sub
End Module
' The example displays output like the following:
'       Thread1 is requesting the mutex
'       Thread2 is requesting the mutex
'       Thread1 has entered the protected area
'       Thread3 is requesting the mutex
'       Thread1 is leaving the protected area
'       Thread1 has released the mutex
'       Thread3 has entered the protected area
'       Thread3 is leaving the protected area
'       Thread3 has released the mutex
'       Thread2 has entered the protected area
'       Thread2 is leaving the protected area
'       Thread2 has released the mutex

I följande exempel anropar WaitOne(Int32) varje tråd metoden för att hämta mutex. Om tidsgränsintervallet förflutit returnerar falsemetoden , och tråden varken hämtar mutex eller får åtkomst till resursen som mutex skyddar. Metoden ReleaseMutex anropas endast av den tråd som hämtar mutex.

using System;
using System.Threading;

class Example
{
    // Create a new Mutex. The creating thread does not own the mutex.
    private static Mutex mut = new Mutex();
    private const int numIterations = 1;
    private const int numThreads = 3;

    static void Main()
    {
        Example ex = new Example();
        ex.StartThreads();
    }

     private void StartThreads()
     {
        // Create the threads that will use the protected resource.
        for(int i = 0; i < numThreads; i++)
        {
            Thread newThread = new Thread(new ThreadStart(ThreadProc));
            newThread.Name = String.Format("Thread{0}", i + 1);
            newThread.Start();
        }

        // The main thread returns to Main and exits, but the application continues to
        // run until all foreground threads have exited.
    }

    private static void ThreadProc()
    {
        for(int i = 0; i < numIterations; i++)
        {
            UseResource();
        }
    }

    // This method represents a resource that must be synchronized
    // so that only one thread at a time can enter.
    private static void UseResource()
    {
        // Wait until it is safe to enter, and do not enter if the request times out.
        Console.WriteLine("{0} is requesting the mutex", Thread.CurrentThread.Name);
        if (mut.WaitOne(1000)) {
           Console.WriteLine("{0} has entered the protected area", 
               Thread.CurrentThread.Name);
   
           // Place code to access non-reentrant resources here.
   
           // Simulate some work.
           Thread.Sleep(5000);
   
           Console.WriteLine("{0} is leaving the protected area", 
               Thread.CurrentThread.Name);
   
           // Release the Mutex.
              mut.ReleaseMutex();
           Console.WriteLine("{0} has released the mutex", 
                             Thread.CurrentThread.Name);
        }
        else {
           Console.WriteLine("{0} will not acquire the mutex", 
                             Thread.CurrentThread.Name);
        }
    }

    ~Example()
    {
       mut.Dispose();
    }
}
// The example displays output like the following:
//       Thread1 is requesting the mutex
//       Thread1 has entered the protected area
//       Thread2 is requesting the mutex
//       Thread3 is requesting the mutex
//       Thread2 will not acquire the mutex
//       Thread3 will not acquire the mutex
//       Thread1 is leaving the protected area
//       Thread1 has released the mutex
Imports System.Threading

Class Example
   ' Create a new Mutex. The creating thread does not own the mutex.
   Private mut As New Mutex()
   Private Const numIterations As Integer = 1
   Private Const numThreads As Integer = 3

   Public Shared Sub Main()
      Dim ex As New Example()
      ex.StartThreads()
   End Sub
   
   Private Sub StartThreads()
        ' Create the threads that will use the protected resource.
        For i As Integer = 0 To numThreads - 1
            Dim newThread As New Thread(AddressOf ThreadProc)
            newThread.Name = String.Format("Thread{0}", i + 1)
            newThread.Start()
        Next

        ' The main thread returns to Main and exits, but the application continues to
        ' run until all foreground threads have exited.
   End Sub

   Private Sub ThreadProc()
        For i As Integer = 0 To numIterations - 1
            UseResource()
        Next
   End Sub

   ' This method represents a resource that must be synchronized
   ' so that only one thread at a time can enter.
   Private Sub UseResource()
        ' Wait until it is safe to enter.
        Console.WriteLine("{0} is requesting the mutex", 
                          Thread.CurrentThread.Name)
        If mut.WaitOne(1000) Then
           Console.WriteLine("{0} has entered the protected area", 
               Thread.CurrentThread.Name)
   
           ' Place code to access non-reentrant resources here.
   
           ' Simulate some work.
           Thread.Sleep(5000)
   
           Console.WriteLine("{0} is leaving the protected area", 
               Thread.CurrentThread.Name)
   
           ' Release the Mutex.
           mut.ReleaseMutex()
           Console.WriteLine("{0} has released the mutex", 
                             Thread.CurrentThread.Name)
        Else
           Console.WriteLine("{0} will not acquire the mutex", 
                             Thread.CurrentThread.Name)
        End If
   End Sub
   
   Protected Overrides Sub Finalize()
      mut.Dispose()
   End Sub
End Class
' The example displays output like the following:
'       Thread1 is requesting the mutex
'       Thread1 has entered the protected area
'       Thread2 is requesting the mutex
'       Thread3 is requesting the mutex
'       Thread2 will not acquire the mutex
'       Thread3 will not acquire the mutex
'       Thread1 is leaving the protected area
'       Thread1 has released the mutex

Kommentarer

När två eller flera trådar behöver komma åt en delad resurs samtidigt behöver systemet en synkroniseringsmekanism för att säkerställa att endast en tråd i taget använder resursen. Mutex är en synkroniseringsprimiter som ger exklusiv åtkomst till den delade resursen till endast en tråd. Om en tråd hämtar en mutex pausas den andra tråden som vill hämta mutex tills den första tråden släpper mutex.

Important

Den här typen implementerar IDisposable gränssnittet. När du har använt typen bör du kassera den på ett direkt eller indirekt sätt. Om du vill ta bort typen direkt anropar du dess Dispose metod i ett try/catch block. Om du vill ta bort det indirekt använder du en språkkonstruktion som using (i C#) eller Using (i Visual Basic). Mer information finns i avsnittet "Använda ett objekt som implementerar IDisposable" i IDisposable gränssnittet.

Du kan använda WaitHandle.WaitOne metoden för att begära ägarskap för en mutex. Den anropande tråden blockerar tills något av följande inträffar:

  • Mutex signaleras för att indikera att det inte ägs. När detta inträffar WaitOne returnerar truemetoden , och den anropande tråden förutsätter ägarskap för mutex och kommer åt resursen som skyddas av mutex. När den har kommit åt resursen måste tråden ReleaseMutex anropa metoden för att frigöra ägarskapet för mutex. Det första exemplet i avsnittet Exempel illustrerar det här mönstret.

  • Tidsgränsintervallet som anges i anropet till en WaitOne metod som har en millisecondsTimeout eller timeout -parameter har förflutit. När detta händer WaitOne returnerar falsemetoden , och den anropande tråden gör inga ytterligare försök att hämta ägarskapet för mutex. I det här fallet bör du strukturera koden så att åtkomst till resursen som skyddas av mutex nekas till den anropande tråden. Eftersom tråden aldrig förvärvade ägarskapet för mutex får den inte anropa ReleaseMutex metoden. Det andra exemplet i avsnittet Exempel illustrerar det här mönstret.

Klassen Mutex framtvingar trådidentitet, så en mutex kan bara släppas av den tråd som hämtade den. Klassen tillämpar däremot Semaphore inte trådidentitet. En mutex kan också skickas över programdomängränser.

Tråden som äger en mutex kan begära samma mutex i upprepade anrop till utan att WaitOne blockera dess körning. Tråden måste dock anropa ReleaseMutex metoden samma antal gånger för att frigöra ägarskapet för mutex.

Mutex Eftersom klassen ärver från WaitHandlekan du även anropa statiska WaitHandle.WaitAll metoder och WaitHandle.WaitAny metoder för att synkronisera åtkomst till en skyddad resurs.

Om en tråd avslutas när den äger en mutex, sägs mutexen vara övergiven. Mutex-tillståndet är inställt på signalerat och nästa väntande tråd får ägarskap. Från och med version 2.0 av .NET Framework genereras en AbandonedMutexException i nästa tråd som hämtar den övergivna mutexen. Innan version 2.0 av .NET Framework utlöstes inget undantag.

Caution

En övergiven mutex indikerar ofta ett allvarligt fel i koden. När en tråd avslutas utan att släppa mutexen kanske datastrukturerna som skyddas av mutex inte är i ett konsekvent tillstånd. Nästa tråd för att begära ägarskap för mutex kan hantera det här undantaget och fortsätta, om datastrukturernas integritet kan verifieras.

När det gäller en systemomfattande mutex kan en övergiven mutex indikera att ett program plötsligt har avslutats (till exempel med hjälp av Windows Task Manager).

Mutexes är av två typer: lokala mutexes, som är namnlösa och namngivna system mutexes. En lokal mutex finns endast inom din process. Den kan användas av valfri tråd i processen som har en referens till objektet Mutex som representerar mutex. Varje namnlöst Mutex objekt representerar en separat lokal mutex.

Namngivna systemljud visas i hela operativsystemet och kan användas för att synkronisera processernas aktiviteter. Du kan skapa ett Mutex objekt som representerar en namngiven system mutex med hjälp av en konstruktor som accepterar ett namn. Operativsystemets objekt kan skapas samtidigt, eller så kan det finnas innan objektet skapas Mutex . Du kan skapa flera Mutex-objekt som representerar samma namngivna systemmutex, och du kan använda OpenExisting-metoden för att öppna en befintlig namngiven systemmutex.

Note

På en server som kör Terminal Services kan ett namngivet system mutex ha två synlighetsnivåer. Om namnet börjar med prefixet Global\visas mutex i alla terminalserversessioner. Om namnet börjar med prefixet Local\visas mutex endast i terminalserversessionen där det skapades. I så fall kan det finnas en separat mutex med samma namn i var och en av de andra terminalserversessionerna på servern. Om du inte anger ett prefix när du skapar ett med namnet mutex, tar det prefixet Local\. I en terminalserversession är två mutexes vars namn endast skiljer sig åt med sina prefix separata mutex och båda är synliga för alla processer i terminalserversessionen. Det vill:s prefixnamn Global\ och Local\ beskriver omfånget för mutex-namnet i förhållande till terminalserversessioner, inte i förhållande till processer.

Caution

Som standard är en namngiven mutex inte begränsad till den användare som skapade den. Andra användare kanske kan öppna och använda mutex, inklusive att störa mutex genom att ange mutex och inte avsluta det. På Unix-liknande operativsystem används filsystemet i implementeringen av namngivna mutexar, och andra användare kanske kan störa namngivna mutexar på mer betydande sätt. För att begränsa åtkomsten till specifika användare på Windows kan du använda en konstruktoröverlagring eller MutexAcl och skicka in en MutexSecurity när du skapar den namngivna mutexen. I Unix-liknande operativsystem finns det för närvarande inget sätt att begränsa åtkomsten till en namngiven mutex. Undvik att använda namngivna mutexes utan åtkomstbegränsningar för system som kan ha obetrodda användare som kör kod.

Omvänt snedstreck (\) är ett reserverat tecken i ett mutex-namn. Använd inte ett omvänt snedstreck (\) i ett mutex-namn förutom det som anges i anteckningen om att använda mutex i terminalserversessioner. Annars kan en DirectoryNotFoundException genereras, även om namnet på mutex representerar en befintlig fil.

Konstruktorer

Name Description
Mutex()

Initierar en ny instans av Mutex klassen med standardegenskaper.

Mutex(Boolean, String, Boolean, MutexSecurity)

Initierar en ny instans av Mutex klassen med ett booleskt värde som anger om den anropande tråden ska ha initial ägarskap för mutexen, en sträng som är namnet på mutexen, en boolesk variabel som när metoden returneras anger om den anropande tråden har beviljats ursprungligt ägarskap för mutex och den åtkomstkontrollsäkerhet som ska tillämpas på den namngivna mutexen.

Mutex(Boolean, String, Boolean)

Initierar en ny instans av Mutex klassen med ett booleskt värde som anger om den anropande tråden ska ha initial ägarskap för mutexen, en sträng som är namnet på mutexen och ett booleskt värde som anger om den anropande tråden har beviljats initial ägarskap för mutex när metoden returneras.

Mutex(Boolean, String, NamedWaitHandleOptions, Boolean)

Initierar en ny instans av Mutex klassen med ett booleskt värde som anger om den anropande tråden ska ha initial ägarskap för mutex, en sträng som är namnet på mutex, alternativ för att ange åtkomst för användaromfattning och sessionsomfattning och ett booleskt värde som när metoden returnerar anger om den anropande tråden har beviljats initial ägarskap för mutex.

Mutex(Boolean, String, NamedWaitHandleOptions)

Initierar en ny instans av Mutex klassen med ett booleskt värde som anger om den anropande tråden ska ha initial ägarskap för mutex, en sträng som är namnet på mutex och alternativ för att ange åtkomst för användaromfattning och sessionsomfång.

Mutex(Boolean, String)

Initierar en ny instans av Mutex klassen med ett booleskt värde som anger om den anropande tråden ska ha initial ägarskap för mutex och en sträng som är namnet på mutexen.

Mutex(Boolean)

Initierar en ny instans av Mutex klassen med ett booleskt värde som anger om den anropande tråden ska ha inledande ägarskap för mutexen.

Mutex(String, NamedWaitHandleOptions)

Initierar en ny instans av Mutex klassen med en sträng som är namnet på mutex och alternativ för att ange åtkomst för användaromfattning och sessionsomfång. Den anropande tråden begär inte att ha initialt ägarskap för mutex.

Fält

Name Description
WaitTimeout

Anger att tidsgränsen för en WaitAny(WaitHandle[], Int32, Boolean) åtgärd uppstod innan någon av väntehandtagen signalerades. Det här fältet är konstant.

(Ärvd från WaitHandle)

Egenskaper

Name Description
Handle
Föråldrad.
Föråldrad.

Hämtar eller anger det interna operativsystemets handtag.

(Ärvd från WaitHandle)
SafeWaitHandle

Hämtar eller anger det interna operativsystemets handtag.

(Ärvd från WaitHandle)

Metoder

Name Description
Close()

Släpper alla resurser som innehas av den aktuella WaitHandle.

(Ärvd från WaitHandle)
CreateObjRef(Type)

Skapar ett objekt som innehåller all relevant information som krävs för att generera en proxy som används för att kommunicera med ett fjärrobjekt.

(Ärvd från MarshalByRefObject)
Dispose()

Släpper alla resurser som används av den aktuella instansen WaitHandle av klassen.

(Ärvd från WaitHandle)
Dispose(Boolean)

När de åsidosättas i en härledd klass släpper du de ohanterade resurser som används av WaitHandle, och släpper eventuellt de hanterade resurserna.

(Ärvd från WaitHandle)
Equals(Object)

Avgör om det angivna objektet är lika med det aktuella objektet.

(Ärvd från Object)
GetAccessControl()

Hämtar ett MutexSecurity objekt som representerar åtkomstkontrollsäkerheten för den namngivna mutexen.

GetHashCode()

Fungerar som standard-hash-funktion.

(Ärvd från Object)
GetLifetimeService()
Föråldrad.

Hämtar det aktuella livslängdstjänstobjektet som styr livslängdsprincipen för den här instansen.

(Ärvd från MarshalByRefObject)
GetType()

Hämtar den aktuella instansen Type .

(Ärvd från Object)
InitializeLifetimeService()
Föråldrad.

Hämtar ett tjänstobjekt för livslängd för att styra livslängdsprincipen för den här instansen.

(Ärvd från MarshalByRefObject)
MemberwiseClone()

Skapar en ytlig kopia av den aktuella Object.

(Ärvd från Object)
MemberwiseClone(Boolean)

Skapar en ytlig kopia av det aktuella MarshalByRefObject objektet.

(Ärvd från MarshalByRefObject)
OpenExisting(String, MutexRights)

Öppnar det angivna namnet mutex, om det redan finns, med önskad säkerhetsåtkomst.

OpenExisting(String, NamedWaitHandleOptions)

Öppnar det angivna namnet mutex, om det redan finns. Om alternativen endast är inställda på den aktuella användaren verifieras objektets åtkomstkontroller för den anropande användaren.

OpenExisting(String)

Öppnar det angivna namnet mutex, om det redan finns.

ReleaseMutex()

Släpper en Mutex gång.

SetAccessControl(MutexSecurity)

Anger åtkomstkontrollsäkerhet för en namngiven system mutex.

ToString()

Returnerar en sträng som representerar det aktuella objektet.

(Ärvd från Object)
TryOpenExisting(String, Mutex)

Öppnar det angivna namnet mutex, om det redan finns, och returnerar ett värde som anger om åtgärden lyckades.

TryOpenExisting(String, MutexRights, Mutex)

Öppnar den angivna namngivna mutexen, om den redan finns, med önskad säkerhetsåtkomst, och returnerar ett värde som anger om åtgärden lyckades.

TryOpenExisting(String, NamedWaitHandleOptions, Mutex)

Öppnar det angivna namnet mutex, om det redan finns, och returnerar ett värde som anger om åtgärden lyckades. Om alternativen endast är inställda på den aktuella användaren verifieras objektets åtkomstkontroller för den anropande användaren.

WaitOne()

Blockerar den aktuella tråden tills strömmen WaitHandle tar emot en signal.

(Ärvd från WaitHandle)
WaitOne(Int32, Boolean)

Blockerar den aktuella tråden tills den aktuella WaitHandle tar emot en signal med ett 32-bitars signerat heltal för att ange tidsintervallet och ange om synkroniseringsdomänen ska avslutas före väntan.

(Ärvd från WaitHandle)
WaitOne(Int32)

Blockerar den aktuella tråden tills strömmen WaitHandle tar emot en signal med hjälp av ett 32-bitars signerat heltal för att ange tidsintervallet i millisekunder.

(Ärvd från WaitHandle)
WaitOne(TimeSpan, Boolean)

Blockerar den aktuella tråden tills den aktuella instansen tar emot en signal med hjälp av en TimeSpan för att ange tidsintervallet och ange om synkroniseringsdomänen ska avslutas före väntan.

(Ärvd från WaitHandle)
WaitOne(TimeSpan)

Blockerar den aktuella tråden tills den aktuella instansen tar emot en signal med hjälp av en TimeSpan för att ange tidsintervallet.

(Ärvd från WaitHandle)

Explicita gränssnittsimplementeringar

Name Description
IDisposable.Dispose()

Detta API stöder produktinfrastrukturen och är inte avsett att användas direkt från koden.

Släpper alla resurser som används av WaitHandle.

(Ärvd från WaitHandle)

Tilläggsmetoder

Name Description
GetAccessControl(Mutex)

Returnerar säkerhetsbeskrivningarna för angivna mutex.

GetSafeWaitHandle(WaitHandle)

Hämtar det säkra handtaget för ett inbyggt väntehandtag för operativsystemet.

SetAccessControl(Mutex, MutexSecurity)

Anger säkerhetsbeskrivningarna för angiven mutex.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Anger ett säkert handtag för ett inbyggt väntehandtag för operativsystemet.

Gäller för

Trådsäkerhet

Den här typen är trådsäker.

Se även