Udostępnij za pośrednictwem


Mutex Konstruktory

Definicja

Inicjuje nowe wystąpienie klasy Mutex.

Przeciążenia

Mutex()

Inicjuje Mutex nowe wystąpienie klasy z domyślnymi właściwościami.

Mutex(Boolean)

Inicjuje nowe wystąpienie Mutex klasy z wartością logiczną wskazującą, czy wątek wywołujący powinien mieć początkową własność mutexu.

Mutex(Boolean, String)

Inicjuje nowe wystąpienie Mutex klasy z wartością logiczną wskazującą, czy wątek wywołujący powinien mieć początkową własność mutexu, oraz ciąg, który jest nazwą mutexu.

Mutex(Boolean, String, Boolean)

Inicjuje nowe wystąpienie Mutex klasy z wartością logiczną, która wskazuje, czy wątek wywołujący powinien mieć początkową własność mutex, ciąg, który jest nazwą mutex, i wartość logiczną, która, gdy metoda zwraca, wskazuje, czy wątek wywołujący otrzymał wstępną własność mutex.

Mutex(Boolean, String, Boolean, MutexSecurity)

Inicjuje nowe wystąpienie Mutex klasy z wartością logiczną, która wskazuje, czy wątek wywołujący powinien mieć początkową własność mutex, ciąg, który jest nazwą mutex, zmienną logiczną, która po powrocie metody wskazuje, czy wątek wywołujący otrzymał wstępną własność mutex, a zabezpieczenia kontroli dostępu do zastosowania do nazwanego mutex.

Mutex()

Źródło:
Mutex.cs
Źródło:
Mutex.cs
Źródło:
Mutex.cs

Inicjuje Mutex nowe wystąpienie klasy z domyślnymi właściwościami.

public:
 Mutex();
public Mutex ();
Public Sub New ()

Przykłady

W poniższym przykładzie kodu pokazano, jak obiekt lokalny Mutex jest używany do synchronizowania dostępu do chronionego zasobu. Wątek, który tworzy mutex, nie jest jego właścicielem początkowo.

// This example shows how a Mutex is used to synchronize access
// to a protected resource. Unlike Monitor, Mutex can be used with
// WaitHandle.WaitAll and WaitAny, and can be passed across
// AppDomain boundaries.
using namespace System;
using namespace System::Threading;
const int numIterations = 1;
const int numThreads = 3;
ref class Test
{
public:

   // Create a new Mutex. The creating thread does not own the
   // Mutex.
   static Mutex^ mut = gcnew Mutex;
   static void MyThreadProc()
   {
      for ( int i = 0; i < numIterations; i++ )
      {
         UseResource();

      }
   }


private:

   // This method represents a resource that must be synchronized
   // so that only one thread at a time can enter.
   static void UseResource()
   {
      
      //Wait until it is OK to enter.
      mut->WaitOne();
      Console::WriteLine( "{0} has entered protected the area", Thread::CurrentThread->Name );
      
      // Place code to access non-reentrant resources here.
      // Simulate some work.
      Thread::Sleep( 500 );
      Console::WriteLine( "{0} is leaving protected the area\r\n", Thread::CurrentThread->Name );
      
      // Release the Mutex.
      mut->ReleaseMutex();
   }

};

int main()
{
   
   // Create the threads that will use the protected resource.
   for ( int i = 0; i < numThreads; i++ )
   {
      Thread^ myThread = gcnew Thread( gcnew ThreadStart( Test::MyThreadProc ) );
      myThread->Name = String::Format( "Thread {0}", i + 1 );
      myThread->Start();

   }
   
   // The main thread exits, but the application continues to 
   // run until all foreground threads have exited.
}
// This example shows how a Mutex is used to synchronize access
// to a protected resource. Unlike Monitor, Mutex can be used with
// WaitHandle.WaitAll and WaitAny, and can be passed across
// AppDomain boundaries.
 
using System;
using System.Threading;

class Test13
{
    // 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 myThread = new Thread(new ThreadStart(MyThreadProc));
            myThread.Name = String.Format("Thread{0}", i + 1);
            myThread.Start();
        }

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

    private static void MyThreadProc()
    {
        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.
        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\r\n", 
            Thread.CurrentThread.Name);
         
        // Release the Mutex.
        mut.ReleaseMutex();
    }
}
' This example shows how a Mutex is used to synchronize access
' to a protected resource. Unlike Monitor, Mutex can be used with
' WaitHandle.WaitAll and WaitAny, and can be passed across
' AppDomain boundaries.
 
Imports System.Threading

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

    <MTAThread> _
    Shared Sub Main()
        ' Create the threads that will use the protected resource.
        Dim i As Integer
        For i = 1 To numThreads
            Dim myThread As New Thread(AddressOf MyThreadProc)
            myThread.Name = [String].Format("Thread{0}", i)
            myThread.Start()
        Next i

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

    End Sub

    Private Shared Sub MyThreadProc()
        Dim i As Integer
        For i = 1 To numIterations
            UseResource()
        Next i
    End Sub

    ' This method represents a resource that must be synchronized
    ' so that only one thread at a time can enter.
    Private Shared Sub UseResource()
        ' Wait until it is safe to enter.
        mut.WaitOne()

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

        ' Place code to access non-reentrant resources here.

        ' Simulate some work
        Thread.Sleep(500)

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

        ' Release Mutex.
        mut.ReleaseMutex()
    End Sub
End Class

Uwagi

Wywoływanie tego przeciążenia konstruktora jest takie samo jak wywoływanie Mutex(Boolean) przeciążenia konstruktora i określanie false początkowej własności elementu mutex. Oznacza to, że wątek wywołujący nie jest właścicielem mutex.

Zobacz też

Dotyczy

Mutex(Boolean)

Źródło:
Mutex.cs
Źródło:
Mutex.cs
Źródło:
Mutex.cs

Inicjuje nowe wystąpienie Mutex klasy z wartością logiczną wskazującą, czy wątek wywołujący powinien mieć początkową własność mutexu.

public:
 Mutex(bool initiallyOwned);
public Mutex (bool initiallyOwned);
new System.Threading.Mutex : bool -> System.Threading.Mutex
Public Sub New (initiallyOwned As Boolean)

Parametry

initiallyOwned
Boolean

true aby nadać początkowej własności wątku wywołującego mutex; w przeciwnym razie , false.

Przykłady

W poniższym przykładzie kodu pokazano, jak obiekt lokalny Mutex jest używany do synchronizowania dostępu do chronionego zasobu. Wątek, który początkowo jest Mutex właścicielem.

using namespace System;
using namespace System::Threading;

const int numIterations = 1;
const int numThreads = 3;

ref class Test
{
public:

   // Create a new Mutex. The creating thread owns the
   // Mutex.
   static Mutex^ mut = gcnew Mutex( true );
   static void MyThreadProc()
   {
      for ( int i = 0; i < numIterations; i++ )
      {
         UseResource();

      }
   }


private:

   // This method represents a resource that must be synchronized
   // so that only one thread at a time can enter.
   static void UseResource()
   {
      
      //Wait until it is OK to enter.
      mut->WaitOne();
      Console::WriteLine( "{0} has entered protected the area", Thread::CurrentThread->Name );
      
      // Place code to access non-reentrant resources here.
      // Simulate some work.
      Thread::Sleep( 500 );
      Console::WriteLine( "{0} is leaving protected the area\r\n", Thread::CurrentThread->Name );
      
      // Release the Mutex.
      mut->ReleaseMutex();
   }

};

int main()
{
   
   // Initialize the Mutex.
   Mutex^ mut = Test::mut;
   
   // Create the threads that will use the protected resource.
   for ( int i = 0; i < numThreads; i++ )
   {
      Thread^ myThread = gcnew Thread( gcnew ThreadStart( Test::MyThreadProc ) );
      myThread->Name = String::Format( "Thread {0}", i + 1 );
      myThread->Start();

   }
   
   // Wait one second before allowing other threads to
   // acquire the Mutex.
   Console::WriteLine( "Creating thread owns the Mutex." );
   Thread::Sleep( 1000 );
   Console::WriteLine( "Creating thread releases the Mutex.\r\n" );
   mut->ReleaseMutex();
}
// The example displays output like the following:
//       Creating thread owns the Mutex.
//       Creating thread releases the Mutex.
//       
//       Thread1 has entered the protected area
//       Thread1 is leaving the protected area
//       
//       Thread2 has entered the protected area
//       Thread2 is leaving the protected area
//       
//       Thread3 has entered the protected area
//       Thread3 is leaving the protected area
using System;
using System.Threading;

class Test
{
    private static Mutex mut;
    private const int numIterations = 1;
    private const int numThreads = 3;

    static void Main()
    {
        // Create a new Mutex. The creating thread owns the Mutex.
        mut = new Mutex(true);
        // Create the threads that will use the protected resource.
        for(int i = 0; i < numThreads; i++)
        {
            Thread myThread = new Thread(new ThreadStart(MyThreadProc));
            myThread.Name = String.Format("Thread{0}", i + 1);
            myThread.Start();
        }

        // Wait one second before allowing other threads to
        // acquire the Mutex.
        Console.WriteLine("Creating thread owns the Mutex.");
        Thread.Sleep(1000);

        Console.WriteLine("Creating thread releases the Mutex.\r\n");
        mut.ReleaseMutex();
    }

    private static void MyThreadProc()
    {
        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.
        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\r\n", 
            Thread.CurrentThread.Name);
         
        // Release the Mutex.
        mut.ReleaseMutex();
    }
}
// The example displays output like the following:
//       Creating thread owns the Mutex.
//       Creating thread releases the Mutex.
//       
//       Thread1 has entered the protected area
//       Thread1 is leaving the protected area
//       
//       Thread2 has entered the protected area
//       Thread2 is leaving the protected area
//       
//       Thread3 has entered the protected area
//       Thread3 is leaving the protected area
Imports System.Threading

Class Test
    ' Create a new Mutex. The creating thread owns the
    ' Mutex.
    Private Shared mut As New Mutex(True)
    Private Const numIterations As Integer = 1
    Private Const numThreads As Integer = 3

    <MTAThread> _
    Shared Sub Main()
        ' Create the threads that will use the protected resource.
        Dim i As Integer
        For i = 1 To numThreads
            Dim myThread As New Thread(AddressOf MyThreadProc)
            myThread.Name = [String].Format("Thread{0}", i)
            myThread.Start()
        Next i

        ' Wait one second before allowing other threads to
        ' acquire the Mutex.
        Console.WriteLine("Creating thread owns the Mutex.")
        Thread.Sleep(1000)

        Console.WriteLine("Creating thread releases the Mutex." & vbCrLf)
        mut.ReleaseMutex()
    End Sub

    Private Shared Sub MyThreadProc()
        Dim i As Integer
        For i = 1 To numIterations
            UseResource()
        Next i
    End Sub

    ' This method represents a resource that must be synchronized
    ' so that only one thread at a time can enter.
    Private Shared Sub UseResource()
        ' Wait until it is safe to enter.
        mut.WaitOne()

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

        ' Place code to access non-reentrant resources here.

        ' Simulate some work
        Thread.Sleep(500)

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

        ' Release Mutex.
        mut.ReleaseMutex()
    End Sub
End Class
' The example displays output like the following:
'       Creating thread owns the Mutex.
'       Creating thread releases the Mutex.
'       
'       Thread1 has entered the protected area
'       Thread1 is leaving the protected area
'       
'       Thread2 has entered the protected area
'       Thread2 is leaving the protected area
'       
'       Thread3 has entered the protected area
'       Thread3 is leaving the protected area

Zobacz też

Dotyczy

Mutex(Boolean, String)

Źródło:
Mutex.cs
Źródło:
Mutex.cs
Źródło:
Mutex.cs

Inicjuje nowe wystąpienie Mutex klasy z wartością logiczną wskazującą, czy wątek wywołujący powinien mieć początkową własność mutexu, oraz ciąg, który jest nazwą mutexu.

public:
 Mutex(bool initiallyOwned, System::String ^ name);
[System.Security.SecurityCritical]
public Mutex (bool initiallyOwned, string name);
public Mutex (bool initiallyOwned, string? name);
public Mutex (bool initiallyOwned, string name);
[<System.Security.SecurityCritical>]
new System.Threading.Mutex : bool * string -> System.Threading.Mutex
new System.Threading.Mutex : bool * string -> System.Threading.Mutex
Public Sub New (initiallyOwned As Boolean, name As String)

Parametry

initiallyOwned
Boolean

true w celu nadania początkowej własności wątku wywołującego nazwanego mutexu systemowego, jeśli nazwany mutex systemu jest tworzony w wyniku tego wywołania; w przeciwnym razie , false.

name
String

Nazwa, jeśli obiekt synchronizacji ma być współużytkowany z innymi procesami; null w przeciwnym razie lub pusty ciąg. W nazwie jest rozróżniana wielkość liter. Znak ukośnika odwrotnego (\) jest zarezerwowany i może być używany tylko do określania przestrzeni nazw. Aby uzyskać więcej informacji na temat przestrzeni nazw, zobacz sekcję uwagi. W zależności od systemu operacyjnego mogą istnieć dalsze ograniczenia dotyczące nazwy. Na przykład w systemach operacyjnych opartych na systemie Unix nazwa po wyłączeniu przestrzeni nazw musi być prawidłową nazwą pliku.

Atrybuty

Wyjątki

Nazwany mutex istnieje i ma zabezpieczenia kontroli dostępu, ale użytkownik nie ma FullControl.

Nazwa name jest niepoprawna. Może to być z różnych powodów, w tym niektóre ograniczenia, które mogą zostać wprowadzone przez system operacyjny, takie jak nieznany prefiks lub nieprawidłowe znaki. Należy pamiętać, że w nazwach i typowych prefiksach "Global\" i "Local\" jest rozróżniana wielkość liter.

-lub-

Wystąpił inny błąd. Właściwość HResult może zawierać więcej informacji.

Tylko system Windows: name określono nieznaną przestrzeń nazw. Aby uzyskać więcej informacji, zobacz Nazwy obiektów .

Wartość name jest za długa. Ograniczenia długości mogą zależeć od systemu operacyjnego lub konfiguracji.

Nie można utworzyć obiektu synchronizacji z podanym name obiektem. Obiekt synchronizacji innego typu może mieć taką samą nazwę.

Tylko program .NET Framework: name jest dłuższy niż MAX_PATH (260 znaków).

Przykłady

W poniższym przykładzie pokazano, jak nazwany mutex jest używany do sygnalizowania między wątkami działającymi w dwóch oddzielnych procesach.

Uruchom ten program z co najmniej dwóch okien poleceń. Każdy proces tworzy Mutex obiekt reprezentujący nazwany mutex MyMutex. Nazwany mutex jest obiektem systemowym, którego okres istnienia jest ograniczony okresami Mutex istnienia obiektów, które go reprezentują. Nazwany mutex jest tworzony podczas pierwszego procesu tworzenia obiektu Mutex . W tym przykładzie nazwany mutex jest własnością pierwszego procesu, który uruchamia program. Nazwany mutex jest niszczony, gdy wszystkie Mutex obiekty reprezentujące je zostały zwolnione.

Przeciążenie konstruktora użyte w tym przykładzie nie może określić wątku wywołującego, czy udzielono początkowej własności nazwanego mutexu. Nie należy używać tego konstruktora do żądania własności początkowej, chyba że można mieć pewność, że wątek utworzy nazwany mutex.

using namespace System;
using namespace System::Threading;

int main()
{
   // Create the named mutex. Only one system object named 
   // "MyMutex" can exist; the local Mutex object represents 
   // this system object, regardless of which process or thread
   // caused "MyMutex" to be created.
   Mutex^ m = gcnew Mutex( false,"MyMutex" );
   
   // Try to gain control of the named mutex. If the mutex is 
   // controlled by another thread, wait for it to be released.        
   Console::WriteLine(  "Waiting for the Mutex." );
   m->WaitOne();
   
   // Keep control of the mutex until the user presses
   // ENTER.
   Console::WriteLine( "This application owns the mutex. "
   "Press ENTER to release the mutex and exit." );
   Console::ReadLine();
   m->ReleaseMutex();
}
using System;
using System.Threading;

public class Test1
{
    public static void Main()
    {
        // Create the named mutex. Only one system object named 
        // "MyMutex" can exist; the local Mutex object represents 
        // this system object, regardless of which process or thread
        // caused "MyMutex" to be created.
        Mutex m = new Mutex(false, "MyMutex");
        
        // Try to gain control of the named mutex. If the mutex is 
        // controlled by another thread, wait for it to be released.        
        Console.WriteLine("Waiting for the Mutex.");
        m.WaitOne();

        // Keep control of the mutex until the user presses
        // ENTER.
        Console.WriteLine("This application owns the mutex. " +
            "Press ENTER to release the mutex and exit.");
        Console.ReadLine();

        m.ReleaseMutex();
    }
}
Imports System.Threading

Public Class Test
   Public Shared Sub Main()
      ' Create the named mutex. Only one system object named 
      ' "MyMutex" can exist; the local Mutex object represents 
      ' this system object, regardless of which process or thread
      ' caused "MyMutex" to be created.
      Dim m As New Mutex(False, "MyMutex")
      
      ' Try to gain control of the named mutex. If the mutex is 
      ' controlled by another thread, wait for it to be released.        
      Console.WriteLine("Waiting for the Mutex.")
      m.WaitOne()
      
      ' Keep control of the mutex until the user presses
      ' ENTER.
      Console.WriteLine("This application owns the mutex. " _
          & "Press ENTER to release the mutex and exit.")
      Console.ReadLine()
      
      m.ReleaseMutex()
   End Sub 
End Class

Uwagi

Element name może mieć prefiks Global\ lub Local\ określać przestrzeń nazw. Po określeniu Global przestrzeni nazw obiekt synchronizacji może być współużytkowany z dowolnymi procesami w systemie. Po określeniu Local przestrzeni nazw, która jest również wartością domyślną, gdy nie określono przestrzeni nazw, obiekt synchronizacji może być współużytkowany z procesami w tej samej sesji. W systemie Windows sesja jest sesją logowania, a usługi są zwykle uruchamiane w innej sesji nieinterakcyjnej. W systemach operacyjnych przypominających system Unix każda powłoka ma własną sesję. Obiekty synchronizacji lokalnej sesji mogą być odpowiednie do synchronizacji między procesami z relacją nadrzędną/podrzędną, w której wszystkie są uruchamiane w tej samej sesji. Aby uzyskać więcej informacji na temat nazw obiektów synchronizacji w systemie Windows, zobacz Nazwy obiektów.

name Jeśli element jest podany, a obiekt synchronizacji żądanego typu już istnieje w przestrzeni nazw, używany jest istniejący obiekt synchronizacji. Jeśli obiekt synchronizacji innego typu już istnieje w przestrzeni nazw, WaitHandleCannotBeOpenedException zgłaszany jest obiekt . W przeciwnym razie zostanie utworzony nowy obiekt synchronizacji.

Jeśli name nie null jest i initiallyOwned jest true, wywołujący wątek jest właścicielem mutex tylko wtedy, gdy nazwany system mutex został utworzony w wyniku tego wywołania. Ponieważ nie ma mechanizmu określania, czy nazwany mutex systemowy został utworzony, lepiej false określić metodę podczas initiallyOwned wywoływania tego przeciążenia konstruktora. Możesz użyć konstruktora Mutex(Boolean, String, Boolean) , jeśli musisz określić własność początkową.

Ten konstruktor inicjuje Mutex obiekt reprezentujący nazwany mutex systemowy. Można utworzyć wiele Mutex obiektów reprezentujących ten sam nazwany system mutex.

Jeśli nazwany mutex został już utworzony z zabezpieczeniami kontroli dostępu, a obiekt wywołujący nie ma MutexRights.FullControl, zgłaszany jest wyjątek. Aby otworzyć istniejący nazwany mutex z uprawnieniami wymaganymi tylko do synchronizowania działań wątku, zobacz metodę OpenExisting .

Jeśli określisz null ciąg lub ciąg pusty dla name, zostanie utworzony lokalny mutex, tak jakby został wywołany Mutex(Boolean) konstruktor. W takim przypadku createdNew wartość to zawsze true.

Ponieważ są one ogólnosystemowe, nazwane mutexes mogą służyć do koordynowania użycia zasobów przez granice procesów.

Uwaga

Na serwerze z uruchomionymi usługami terminali nazwany mutex systemu może mieć dwa poziomy widoczności. Jeśli nazwa zaczyna się od prefiksu Global\, mutex jest widoczny we wszystkich sesjach serwera terminali. Jeśli nazwa zaczyna się od prefiksu Local\, mutex jest widoczny tylko w sesji serwera terminali, w której został utworzony. W takim przypadku oddzielny mutex o tej samej nazwie może istnieć w każdej z pozostałych sesji serwera terminali na serwerze. Jeśli nie określisz prefiksu podczas tworzenia nazwanego mutexu, przyjmuje prefiks Local\. W sesji serwera terminalu dwa elementy mutex, których nazwy różnią się tylko ich prefiksami, są oddzielnymi mutexami, a oba są widoczne dla wszystkich procesów w sesji serwera terminalu. Oznacza to, że nazwy Global\ prefiksów i Local\ opisują zakres nazwy mutex względem sesji serwera terminali, a nie względem procesów.

Przestroga

Domyślnie nazwany mutex nie jest ograniczony do użytkownika, który go utworzył. Inni użytkownicy mogą być w stanie otworzyć i użyć mutex, w tym zakłócać działanie mutex, wprowadzając mutex i nie zamykając go. W systemach operacyjnych podobnych do unix system plików jest używany w implementacji nazwanych mutexes, a inni użytkownicy mogą zakłócać nazwane mutexes w bardziej znaczący sposób. W systemie Windows, aby ograniczyć dostęp do określonych użytkowników, można użyć przeciążenia konstruktora lub MutexAcl przekazać MutexSecurity element podczas tworzenia nazwanego mutexu. Obecnie w systemach operacyjnych podobnych do systemu Unix nie ma możliwości ograniczenia dostępu do nazwanego mutexu. Unikaj używania nazwanych mutexes bez ograniczeń dostępu w systemach, które mogą mieć niezaufanych użytkowników z uruchomionym kodem.

Ukośnik odwrotny (\) jest zastrzeżonym znakiem w nazwie mutex. Nie należy używać ukośnika odwrotnego (\) w nazwie mutex z wyjątkiem określonej w notatce dotyczącej używania mutexes w sesjach serwera terminali. DirectoryNotFoundException W przeciwnym razie może zostać zgłoszony błąd, mimo że nazwa mutex reprezentuje istniejący plik.

Zobacz też

Dotyczy

Mutex(Boolean, String, Boolean)

Źródło:
Mutex.cs
Źródło:
Mutex.cs
Źródło:
Mutex.cs

Inicjuje nowe wystąpienie Mutex klasy z wartością logiczną, która wskazuje, czy wątek wywołujący powinien mieć początkową własność mutex, ciąg, który jest nazwą mutex, i wartość logiczną, która, gdy metoda zwraca, wskazuje, czy wątek wywołujący otrzymał wstępną własność mutex.

public:
 Mutex(bool initiallyOwned, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew);
[System.Security.SecurityCritical]
public Mutex (bool initiallyOwned, string name, out bool createdNew);
public Mutex (bool initiallyOwned, string? name, out bool createdNew);
public Mutex (bool initiallyOwned, string name, out bool createdNew);
[<System.Security.SecurityCritical>]
new System.Threading.Mutex : bool * string * bool -> System.Threading.Mutex
new System.Threading.Mutex : bool * string * bool -> System.Threading.Mutex
Public Sub New (initiallyOwned As Boolean, name As String, ByRef createdNew As Boolean)

Parametry

initiallyOwned
Boolean

true w celu nadania początkowej własności wątku wywołującego nazwanego mutexu systemowego, jeśli nazwany mutex systemu jest tworzony w wyniku tego wywołania; w przeciwnym razie , false.

name
String

Nazwa, jeśli obiekt synchronizacji ma być współużytkowany z innymi procesami; null w przeciwnym razie lub pusty ciąg. W nazwie jest rozróżniana wielkość liter. Znak ukośnika odwrotnego (\) jest zarezerwowany i może być używany tylko do określania przestrzeni nazw. Aby uzyskać więcej informacji na temat przestrzeni nazw, zobacz sekcję uwagi. W zależności od systemu operacyjnego mogą istnieć dalsze ograniczenia dotyczące nazwy. Na przykład w systemach operacyjnych opartych na systemie Unix nazwa po wyłączeniu przestrzeni nazw musi być prawidłową nazwą pliku.

createdNew
Boolean

Gdy ta metoda zwraca wartość logiczną, czyli true jeśli został utworzony lokalny mutex (czyli jeśli name jest lub null ciąg pusty) lub jeśli został utworzony określony nazwany mutex systemowy; false jeśli określony nazwany mutex systemowy już istnieje. Ten parametr jest przekazywany jako niezainicjowany.

Atrybuty

Wyjątki

Nazwany mutex istnieje i ma zabezpieczenia kontroli dostępu, ale użytkownik nie ma FullControl.

Nazwa name jest niepoprawna. Może to być z różnych powodów, w tym niektóre ograniczenia, które mogą zostać wprowadzone przez system operacyjny, takie jak nieznany prefiks lub nieprawidłowe znaki. Należy pamiętać, że w nazwach i typowych prefiksach "Global\" i "Local\" jest rozróżniana wielkość liter.

-lub-

Wystąpił inny błąd. Właściwość HResult może zawierać więcej informacji.

Tylko system Windows: name określono nieznaną przestrzeń nazw. Aby uzyskać więcej informacji, zobacz Nazwy obiektów .

Wartość name jest za długa. Ograniczenia długości mogą zależeć od systemu operacyjnego lub konfiguracji.

Nie można utworzyć obiektu synchronizacji z podanym name obiektem. Obiekt synchronizacji innego typu może mieć taką samą nazwę.

Tylko program .NET Framework: name jest dłuższy niż MAX_PATH (260 znaków).

Przykłady

Poniższy przykład kodu pokazuje, jak nazwany mutex jest używany do sygnalizowania między procesami lub wątkami. Uruchom ten program z co najmniej dwóch okien poleceń. Każdy proces tworzy Mutex obiekt reprezentujący nazwany mutex "MyMutex". Nazwany mutex jest obiektem systemowym. W tym przykładzie jego okres istnienia jest powiązany z okresami Mutex istnienia obiektów, które je reprezentują. Nazwany mutex jest tworzony, gdy pierwszy proces tworzy swój obiekt lokalny Mutex i niszczony, gdy wszystkie Mutex obiekty reprezentujące go zostały zwolnione. Nazwany mutex jest początkowo własnością pierwszego procesu. Drugi proces i wszystkie kolejne procesy czekają na wcześniejsze procesy, aby zwolnić nazwany mutex.

// This example shows how a named mutex is used to signal between
// processes or threads.
// Run this program from two (or more) command windows. Each process
// creates a Mutex object that represents the named mutex "MyMutex".
// The named mutex is a system object whose lifetime is bounded by the
// lifetimes of the Mutex objects that represent it. The named mutex
// is created when the first process creates its local Mutex; in this
// example, the named mutex is owned by the first process. The named 
// mutex is destroyed when all the Mutex objects that represent it
// have been released. 
// The second process (and any subsequent process) waits for earlier
// processes to release the named mutex.
using namespace System;
using namespace System::Threading;
int main()
{
   
   // Set this variable to false if you do not want to request 
   // initial ownership of the named mutex.
   bool requestInitialOwnership = true;
   bool mutexWasCreated;
   
   // Request initial ownership of the named mutex by passing
   // true for the first parameter. Only one system object named 
   // "MyMutex" can exist; the local Mutex object represents 
   // this system object. If "MyMutex" is created by this call,
   // then mutexWasCreated contains true; otherwise, it contains
   // false.
   Mutex^ m = gcnew Mutex( requestInitialOwnership, "MyMutex", mutexWasCreated );
   
   // This thread owns the mutex only if it both requested 
   // initial ownership and created the named mutex. Otherwise,
   // it can request the named mutex by calling WaitOne.
   if (  !(requestInitialOwnership && mutexWasCreated) )
   {
      Console::WriteLine(  "Waiting for the named mutex." );
      m->WaitOne();
   }

   
   // Once the process has gained control of the named mutex,
   // hold onto it until the user presses ENTER.
   Console::WriteLine(  "This process owns the named mutex. "
    "Press ENTER to release the mutex and exit." );
   Console::ReadLine();
   
   // Call ReleaseMutex to allow other threads to gain control
   // of the named mutex. If you keep a reference to the local
   // Mutex, you can call WaitOne to request control of the 
   // named mutex.
   m->ReleaseMutex();
}
// This example shows how a named mutex is used to signal between
// processes or threads.
// Run this program from two (or more) command windows. Each process
// creates a Mutex object that represents the named mutex "MyMutex".
// The named mutex is a system object whose lifetime is bounded by the
// lifetimes of the Mutex objects that represent it. The named mutex
// is created when the first process creates its local Mutex; in this
// example, the named mutex is owned by the first process. The named 
// mutex is destroyed when all the Mutex objects that represent it
// have been released. 
// The second process (and any subsequent process) waits for earlier
// processes to release the named mutex.

using System;
using System.Threading;

public class Test12
{
    public static void Main()
    {
        // Set this variable to false if you do not want to request 
        // initial ownership of the named mutex.
        bool requestInitialOwnership = true;
        bool mutexWasCreated;

        // Request initial ownership of the named mutex by passing
        // true for the first parameter. Only one system object named 
        // "MyMutex" can exist; the local Mutex object represents 
        // this system object. If "MyMutex" is created by this call,
        // then mutexWasCreated contains true; otherwise, it contains
        // false.
        Mutex m = new Mutex(requestInitialOwnership, 
                            "MyMutex", 
                            out mutexWasCreated);
        
        // This thread owns the mutex only if it both requested 
        // initial ownership and created the named mutex. Otherwise,
        // it can request the named mutex by calling WaitOne.
        if (!(requestInitialOwnership && mutexWasCreated))
        {
            Console.WriteLine("Waiting for the named mutex.");
            m.WaitOne();
        }

        // Once the process has gained control of the named mutex,
        // hold onto it until the user presses ENTER.
        Console.WriteLine("This process owns the named mutex. " +
            "Press ENTER to release the mutex and exit.");
        Console.ReadLine();

        // Call ReleaseMutex to allow other threads to gain control
        // of the named mutex. If you keep a reference to the local
        // Mutex, you can call WaitOne to request control of the 
        // named mutex.
        m.ReleaseMutex();
    }
}
' This example shows how a named mutex is used to signal between
' processes or threads.
' Run this program from two (or more) command windows. Each process
' creates a Mutex object that represents the named mutex "MyMutex".
' The named mutex is a system object whose lifetime is bounded by the
' lifetimes of the Mutex objects that represent it. The named mutex
' is created when the first process creates its local Mutex; in this
' example, the named mutex is owned by the first process. The named 
' mutex is destroyed when all the Mutex objects that represent it
' have been released. 
' The second process (and any subsequent process) waits for earlier
' processes to release the named mutex.

Imports System.Threading

Public Class Test
   
   <MTAThread> _
   Public Shared Sub Main()
      ' Set this variable to false if you do not want to request 
      ' initial ownership of the named mutex.
      Dim requestInitialOwnership As Boolean = True
      Dim mutexWasCreated As Boolean
      
      ' Request initial ownership of the named mutex by passing
      ' true for the first parameter. Only one system object named 
      ' "MyMutex" can exist; the local Mutex object represents 
      ' this system object. If "MyMutex" is created by this call,
      ' then mutexWasCreated contains true; otherwise, it contains
      ' false.
      Dim m As New Mutex(requestInitialOwnership, "MyMutex", _
          mutexWasCreated)
      
      ' This thread owns the mutex only if it both requested 
      ' initial ownership and created the named mutex. Otherwise,
      ' it can request the named mutex by calling WaitOne.
      If Not (requestInitialOwnership And mutexWasCreated) Then
         Console.WriteLine("Waiting for the named mutex.")
         m.WaitOne()
      End If
      
      ' Once the process has gained control of the named mutex,
      ' hold onto it until the user presses ENTER.
      Console.WriteLine("This process owns the named mutex. " _
          & "Press ENTER to release the mutex and exit.")
      Console.ReadLine()
      
      ' Call ReleaseMutex to allow other threads to gain control
      ' of the named mutex. If you keep a reference to the local
      ' Mutex, you can call WaitOne to request control of the 
      ' named mutex.
      m.ReleaseMutex()
   End Sub
End Class

Uwagi

Element name może mieć prefiks Global\ lub Local\ określać przestrzeń nazw. Po określeniu Global przestrzeni nazw obiekt synchronizacji może być współużytkowany z dowolnymi procesami w systemie. Po określeniu Local przestrzeni nazw, która jest również wartością domyślną, gdy nie określono przestrzeni nazw, obiekt synchronizacji może być współużytkowany z procesami w tej samej sesji. W systemie Windows sesja jest sesją logowania, a usługi są zwykle uruchamiane w innej sesji nieinterakcyjnej. W systemach operacyjnych przypominających system Unix każda powłoka ma własną sesję. Obiekty synchronizacji lokalnej sesji mogą być odpowiednie do synchronizacji między procesami z relacją nadrzędną/podrzędną, w której wszystkie są uruchamiane w tej samej sesji. Aby uzyskać więcej informacji na temat nazw obiektów synchronizacji w systemie Windows, zobacz Nazwy obiektów.

name Jeśli element jest podany, a obiekt synchronizacji żądanego typu już istnieje w przestrzeni nazw, używany jest istniejący obiekt synchronizacji. Jeśli obiekt synchronizacji innego typu już istnieje w przestrzeni nazw, WaitHandleCannotBeOpenedException zgłaszany jest obiekt . W przeciwnym razie zostanie utworzony nowy obiekt synchronizacji.

Jeśli name nie null jest i initiallyOwned jest true, wywołujący wątek jest właścicielem nazwanego mutex tylko wtedy, gdy createdNew jest true po wywołaniu. W przeciwnym razie wątek może zażądać mutex, wywołując metodę WaitOne .

Ten konstruktor inicjuje Mutex obiekt reprezentujący nazwany mutex systemowy. Można utworzyć wiele Mutex obiektów reprezentujących ten sam nazwany system mutex.

Jeśli nazwany mutex został już utworzony z zabezpieczeniami kontroli dostępu, a obiekt wywołujący nie ma MutexRights.FullControl praw, zgłaszany jest wyjątek. Aby otworzyć istniejący nazwany mutex z uprawnieniami wymaganymi tylko do synchronizowania działań wątku, zobacz metodę OpenExisting .

Jeśli określisz null ciąg lub ciąg pusty dla name, zostanie utworzony lokalny mutex, tak jakby został wywołany Mutex(Boolean) konstruktor. W takim przypadku createdNew wartość to zawsze true.

Ponieważ są one ogólnosystemowe, nazwane mutexes mogą służyć do koordynowania użycia zasobów przez granice procesów.

Uwaga

Na serwerze z uruchomionymi usługami terminali nazwany mutex systemu może mieć dwa poziomy widoczności. Jeśli nazwa zaczyna się od prefiksu Global\, mutex jest widoczny we wszystkich sesjach serwera terminali. Jeśli nazwa zaczyna się od prefiksu Local\, mutex jest widoczny tylko w sesji serwera terminali, w której został utworzony. W takim przypadku oddzielny mutex o tej samej nazwie może istnieć w każdej z pozostałych sesji serwera terminali na serwerze. Jeśli nie określisz prefiksu podczas tworzenia nazwanego mutexu, przyjmuje prefiks Local\. W sesji serwera terminalu dwa elementy mutex, których nazwy różnią się tylko ich prefiksami, są oddzielnymi mutexami, a oba są widoczne dla wszystkich procesów w sesji serwera terminalu. Oznacza to, że nazwy Global\ prefiksów i Local\ opisują zakres nazwy mutex względem sesji serwera terminali, a nie względem procesów.

Przestroga

Domyślnie nazwany mutex nie jest ograniczony do użytkownika, który go utworzył. Inni użytkownicy mogą być w stanie otworzyć i użyć mutex, w tym zakłócać działanie mutex, wprowadzając mutex i nie zamykając go. W systemach operacyjnych podobnych do unix system plików jest używany w implementacji nazwanych mutexes, a inni użytkownicy mogą zakłócać nazwane mutexes w bardziej znaczący sposób. W systemie Windows, aby ograniczyć dostęp do określonych użytkowników, można użyć przeciążenia konstruktora lub MutexAcl przekazać MutexSecurity element podczas tworzenia nazwanego mutexu. Obecnie w systemach operacyjnych podobnych do systemu Unix nie ma możliwości ograniczenia dostępu do nazwanego mutexu. Unikaj używania nazwanych mutexes bez ograniczeń dostępu w systemach, które mogą mieć niezaufanych użytkowników z uruchomionym kodem.

Ukośnik odwrotny (\) jest zastrzeżonym znakiem w nazwie mutex. Nie należy używać ukośnika odwrotnego (\) w nazwie mutex z wyjątkiem określonej w notatce dotyczącej używania mutexes w sesjach serwera terminali. DirectoryNotFoundException W przeciwnym razie może zostać zgłoszony błąd, mimo że nazwa mutex reprezentuje istniejący plik.

Zobacz też

Dotyczy

Mutex(Boolean, String, Boolean, MutexSecurity)

Inicjuje nowe wystąpienie Mutex klasy z wartością logiczną, która wskazuje, czy wątek wywołujący powinien mieć początkową własność mutex, ciąg, który jest nazwą mutex, zmienną logiczną, która po powrocie metody wskazuje, czy wątek wywołujący otrzymał wstępną własność mutex, a zabezpieczenia kontroli dostępu do zastosowania do nazwanego mutex.

public:
 Mutex(bool initiallyOwned, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew, System::Security::AccessControl::MutexSecurity ^ mutexSecurity);
public Mutex (bool initiallyOwned, string name, out bool createdNew, System.Security.AccessControl.MutexSecurity mutexSecurity);
[System.Security.SecurityCritical]
public Mutex (bool initiallyOwned, string name, out bool createdNew, System.Security.AccessControl.MutexSecurity mutexSecurity);
new System.Threading.Mutex : bool * string * bool * System.Security.AccessControl.MutexSecurity -> System.Threading.Mutex
[<System.Security.SecurityCritical>]
new System.Threading.Mutex : bool * string * bool * System.Security.AccessControl.MutexSecurity -> System.Threading.Mutex
Public Sub New (initiallyOwned As Boolean, name As String, ByRef createdNew As Boolean, mutexSecurity As MutexSecurity)

Parametry

initiallyOwned
Boolean

true w celu nadania początkowej własności wątku wywołującego nazwanego mutexu systemowego, jeśli nazwany mutex systemu jest tworzony w wyniku tego wywołania; w przeciwnym razie , false.

name
String

Nazwa, jeśli obiekt synchronizacji ma być współużytkowany z innymi procesami; null w przeciwnym razie lub pusty ciąg. W nazwie jest rozróżniana wielkość liter. Znak ukośnika odwrotnego (\) jest zarezerwowany i może być używany tylko do określania przestrzeni nazw. Aby uzyskać więcej informacji na temat przestrzeni nazw, zobacz sekcję uwagi. W zależności od systemu operacyjnego mogą istnieć dalsze ograniczenia dotyczące nazwy. Na przykład w systemach operacyjnych opartych na systemie Unix nazwa po wyłączeniu przestrzeni nazw musi być prawidłową nazwą pliku.

createdNew
Boolean

Gdy ta metoda zwraca wartość logiczną, czyli true jeśli został utworzony lokalny mutex (czyli jeśli name jest lub null ciąg pusty) lub jeśli został utworzony określony nazwany mutex systemowy; false jeśli określony nazwany mutex systemowy już istnieje. Ten parametr jest przekazywany jako niezainicjowany.

mutexSecurity
MutexSecurity

MutexSecurity Obiekt reprezentujący zabezpieczenia kontroli dostępu, które mają zostać zastosowane do nazwanego mutexu systemowego.

Atrybuty

Wyjątki

Nazwa name jest niepoprawna. Może to być z różnych powodów, w tym niektóre ograniczenia, które mogą zostać wprowadzone przez system operacyjny, takie jak nieznany prefiks lub nieprawidłowe znaki. Należy pamiętać, że w nazwach i typowych prefiksach "Global\" i "Local\" jest rozróżniana wielkość liter.

-lub-

Wystąpił inny błąd. Właściwość HResult może zawierać więcej informacji.

Tylko system Windows: name określono nieznaną przestrzeń nazw. Aby uzyskać więcej informacji, zobacz Nazwy obiektów .

Wartość name jest za długa. Ograniczenia długości mogą zależeć od systemu operacyjnego lub konfiguracji.

Nazwany mutex istnieje i ma zabezpieczenia kontroli dostępu, ale użytkownik nie ma FullControl.

Nie można utworzyć obiektu synchronizacji z podanym name obiektem. Obiekt synchronizacji innego typu może mieć taką samą nazwę.

Tylko program .NET Framework: name jest dłuższy niż MAX_PATH (260 znaków).

Przykłady

W poniższym przykładzie kodu pokazano zachowanie między procesami nazwanego mutexu z zabezpieczeniami kontroli dostępu. W przykładzie użyto OpenExisting(String) przeciążenia metody do przetestowania istnienia nazwanego mutexu.

Jeśli mutex nie istnieje, jest tworzony z początkowym własnością i zabezpieczeniami kontroli dostępu, które odmawia bieżącemu użytkownikowi prawa do korzystania z mutex, ale przyznaje prawo do odczytu i zmiany uprawnień do mutex.

Jeśli uruchomisz skompilowany przykład z dwóch okien poleceń, druga kopia zgłosi wyjątek naruszenia dostępu w wywołaniu metody OpenExisting(String). Wyjątek zostanie przechwycony, a w przykładzie użyto OpenExisting(String, MutexRights) przeciążenia metody, aby otworzyć mutex z prawami wymaganymi do odczytu i zmiany uprawnień.

Po zmianie uprawnień zostanie otwarty mutex z uprawnieniami wymaganymi do wprowadzenia i zwolnienia. Jeśli uruchomisz skompilowany przykład z trzeciego okna polecenia, zostanie ono uruchomione przy użyciu nowych uprawnień.

using namespace System;
using namespace System::Threading;
using namespace System::Security::AccessControl;
using namespace System::Security::Permissions;

public ref class Example
{
public:
   [SecurityPermissionAttribute(SecurityAction::Demand,Flags=SecurityPermissionFlag::UnmanagedCode)]
   static void Main()
   {
      String^ mutexName = L"MutexExample4";

      Mutex^ m = nullptr;
      bool doesNotExist = false;
      bool unauthorized = false;
      
      // The value of this variable is set by the mutex
      // constructor. It is true if the named system mutex was
      // created, and false if the named mutex already existed.
      //
      bool mutexWasCreated = false;

      // Attempt to open the named mutex.
      try
      {
         // Open the mutex with (MutexRights.Synchronize |
         // MutexRights.Modify), to enter and release the
         // named mutex.
         //
         m = Mutex::OpenExisting( mutexName );
      }
      catch ( WaitHandleCannotBeOpenedException^ ) 
      {
         Console::WriteLine( L"Mutex does not exist." );
         doesNotExist = true;
      }
      catch ( UnauthorizedAccessException^ ex ) 
      {
         Console::WriteLine( L"Unauthorized access: {0}", ex->Message );
         unauthorized = true;
      }

      // There are three cases: (1) The mutex does not exist.
      // (2) The mutex exists, but the current user doesn't
      // have access. (3) The mutex exists and the user has
      // access.
      //
      if ( doesNotExist )
      {
         // The mutex does not exist, so create it.
         // Create an access control list (ACL) that denies the
         // current user the right to enter or release the
         // mutex, but allows the right to read and change
         // security information for the mutex.
         //
         String^ user = String::Concat( Environment::UserDomainName, L"\\",
            Environment::UserName );
         MutexSecurity^ mSec = gcnew MutexSecurity;

         MutexAccessRule^ rule = gcnew MutexAccessRule( user,
            static_cast<MutexRights>(
               MutexRights::Synchronize |
               MutexRights::Modify),
            AccessControlType::Deny );
         mSec->AddAccessRule( rule );

         rule = gcnew MutexAccessRule( user,
            static_cast<MutexRights>(
               MutexRights::ReadPermissions |
                MutexRights::ChangePermissions),
            AccessControlType::Allow );
         mSec->AddAccessRule( rule );
         
         // Create a Mutex object that represents the system
         // mutex named by the constant 'mutexName', with
         // initial ownership for this thread, and with the
         // specified security access. The Boolean value that
         // indicates creation of the underlying system object
         // is placed in mutexWasCreated.
         //
         m = gcnew Mutex( true,mutexName, mutexWasCreated,mSec );
         
         // If the named system mutex was created, it can be
         // used by the current instance of this program, even
         // though the current user is denied access. The current
         // program owns the mutex. Otherwise, exit the program.
         //
         if ( mutexWasCreated )
         {
            Console::WriteLine( L"Created the mutex." );
         }
         else
         {
            Console::WriteLine( L"Unable to create the mutex." );
            return;
         }
      }
      else if ( unauthorized )
      {
         // Open the mutex to read and change the access control
         // security. The access control security defined above
         // allows the current user to do this.
         //
         try
         {
            m = Mutex::OpenExisting( mutexName,
               static_cast<MutexRights>(
                  MutexRights::ReadPermissions |
                  MutexRights::ChangePermissions) );
            
            // Get the current ACL. This requires
            // MutexRights.ReadPermissions.
            MutexSecurity^ mSec = m->GetAccessControl();

            String^ user = String::Concat( Environment::UserDomainName,
               L"\\", Environment::UserName );
            
            // First, the rule that denied the current user
            // the right to enter and release the mutex must
            // be removed.
            MutexAccessRule^ rule = gcnew MutexAccessRule( user,
               static_cast<MutexRights>(
                  MutexRights::Synchronize |
                  MutexRights::Modify),
               AccessControlType::Deny );
            mSec->RemoveAccessRule( rule );
            
            // Now grant the user the correct rights.
            //
            rule = gcnew MutexAccessRule( user,
               static_cast<MutexRights>(
                  MutexRights::Synchronize |
                  MutexRights::Modify),
               AccessControlType::Allow );
            mSec->AddAccessRule( rule );
            
            // Update the ACL. This requires
            // MutexRights.ChangePermissions.
            m->SetAccessControl( mSec );

            Console::WriteLine( L"Updated mutex security." );
            
            // Open the mutex with (MutexRights.Synchronize
            // | MutexRights.Modify), the rights required to
            // enter and release the mutex.
            //
            m = Mutex::OpenExisting( mutexName );
         }
         catch ( UnauthorizedAccessException^ ex ) 
         {
            Console::WriteLine(
               L"Unable to change permissions: {0}", ex->Message );
            return;
         }
      }
      
      // If this program created the mutex, it already owns
      // the mutex.
      //
      if ( !mutexWasCreated )
      {
         // Enter the mutex, and hold it until the program
         // exits.
         //
         try
         {
            Console::WriteLine( L"Wait for the mutex." );
            m->WaitOne();
            Console::WriteLine( L"Entered the mutex." );
         }
         catch ( UnauthorizedAccessException^ ex ) 
         {
            Console::WriteLine( L"Unauthorized access: {0}",
               ex->Message );
         }
      }

      Console::WriteLine( L"Press the Enter key to exit." );
      Console::ReadLine();
      m->ReleaseMutex();
      m->Dispose();
   }
};

int main()
{
   Example::Main();
}
using System;
using System.Threading;
using System.Security.AccessControl;

internal class Example
{
    internal static void Main()
    {
        const string mutexName = "MutexExample4";

        Mutex m = null;
        bool doesNotExist = false;
        bool unauthorized = false;

        // The value of this variable is set by the mutex
        // constructor. It is true if the named system mutex was
        // created, and false if the named mutex already existed.
        //
        bool mutexWasCreated = false;

        // Attempt to open the named mutex.
        try
        {
            // Open the mutex with (MutexRights.Synchronize |
            // MutexRights.Modify), to enter and release the
            // named mutex.
            //
            m = Mutex.OpenExisting(mutexName);
        }
        catch(WaitHandleCannotBeOpenedException)
        {
            Console.WriteLine("Mutex does not exist.");
            doesNotExist = true;
        }
        catch(UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
            unauthorized = true;
        }

        // There are three cases: (1) The mutex does not exist.
        // (2) The mutex exists, but the current user doesn't 
        // have access. (3) The mutex exists and the user has
        // access.
        //
        if (doesNotExist)
        {
            // The mutex does not exist, so create it.

            // Create an access control list (ACL) that denies the
            // current user the right to enter or release the 
            // mutex, but allows the right to read and change
            // security information for the mutex.
            //
            string user = Environment.UserDomainName + "\\"
                + Environment.UserName;
            var mSec = new MutexSecurity();

            MutexAccessRule rule = new MutexAccessRule(user, 
                MutexRights.Synchronize | MutexRights.Modify, 
                AccessControlType.Deny);
            mSec.AddAccessRule(rule);

            rule = new MutexAccessRule(user, 
                MutexRights.ReadPermissions | MutexRights.ChangePermissions,
                AccessControlType.Allow);
            mSec.AddAccessRule(rule);

            // Create a Mutex object that represents the system
            // mutex named by the constant 'mutexName', with
            // initial ownership for this thread, and with the
            // specified security access. The Boolean value that 
            // indicates creation of the underlying system object
            // is placed in mutexWasCreated.
            //
            m = new Mutex(true, mutexName, out mutexWasCreated, mSec);

            // If the named system mutex was created, it can be
            // used by the current instance of this program, even 
            // though the current user is denied access. The current
            // program owns the mutex. Otherwise, exit the program.
            // 
            if (mutexWasCreated)
            {
                Console.WriteLine("Created the mutex.");
            }
            else
            {
                Console.WriteLine("Unable to create the mutex.");
                return;
            }
        }
        else if (unauthorized)
        {
            // Open the mutex to read and change the access control
            // security. The access control security defined above
            // allows the current user to do this.
            //
            try
            {
                m = Mutex.OpenExisting(mutexName, 
                    MutexRights.ReadPermissions | MutexRights.ChangePermissions);

                // Get the current ACL. This requires 
                // MutexRights.ReadPermissions.
                MutexSecurity mSec = m.GetAccessControl();
                
                string user = Environment.UserDomainName + "\\"
                    + Environment.UserName;

                // First, the rule that denied the current user 
                // the right to enter and release the mutex must
                // be removed.
                MutexAccessRule rule = new MutexAccessRule(user, 
                     MutexRights.Synchronize | MutexRights.Modify,
                     AccessControlType.Deny);
                mSec.RemoveAccessRule(rule);

                // Now grant the user the correct rights.
                // 
                rule = new MutexAccessRule(user, 
                    MutexRights.Synchronize | MutexRights.Modify,
                    AccessControlType.Allow);
                mSec.AddAccessRule(rule);

                // Update the ACL. This requires
                // MutexRights.ChangePermissions.
                m.SetAccessControl(mSec);

                Console.WriteLine("Updated mutex security.");

                // Open the mutex with (MutexRights.Synchronize 
                // | MutexRights.Modify), the rights required to
                // enter and release the mutex.
                //
                m = Mutex.OpenExisting(mutexName);
            }
            catch(UnauthorizedAccessException ex)
            {
                Console.WriteLine("Unable to change permissions: {0}",
                    ex.Message);
                return;
            }
        }

        // If this program created the mutex, it already owns
        // the mutex.
        //
        if (!mutexWasCreated)
        {
            // Enter the mutex, and hold it until the program
            // exits.
            //
            try
            {
                Console.WriteLine("Wait for the mutex.");
                m.WaitOne();
                Console.WriteLine("Entered the mutex.");
            }
            catch(UnauthorizedAccessException ex)
            {
                Console.WriteLine("Unauthorized access: {0}", ex.Message);
            }
        }

        Console.WriteLine("Press the Enter key to exit.");
        Console.ReadLine();
        m.ReleaseMutex();
        m.Dispose();
    }
}
Imports System.Threading
Imports System.Security.AccessControl

Friend Class Example

    <MTAThread> _
    Friend Shared Sub Main()
        Const mutexName As String = "MutexExample4"

        Dim m As Mutex = Nothing
        Dim doesNotExist as Boolean = False
        Dim unauthorized As Boolean = False

        ' The value of this variable is set by the mutex
        ' constructor. It is True if the named system mutex was
        ' created, and False if the named mutex already existed.
        '
        Dim mutexWasCreated As Boolean

        ' Attempt to open the named mutex.
        Try
            ' Open the mutex with (MutexRights.Synchronize Or
            ' MutexRights.Modify), to enter and release the
            ' named mutex.
            '
            m = Mutex.OpenExisting(mutexName)
        Catch ex As WaitHandleCannotBeOpenedException
            Console.WriteLine("Mutex does not exist.")
            doesNotExist = True
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", ex.Message)
            unauthorized = True
        End Try

        ' There are three cases: (1) The mutex does not exist.
        ' (2) The mutex exists, but the current user doesn't 
        ' have access. (3) The mutex exists and the user has
        ' access.
        '
        If doesNotExist Then
            ' The mutex does not exist, so create it.

            ' Create an access control list (ACL) that denies the
            ' current user the right to enter or release the 
            ' mutex, but allows the right to read and change
            ' security information for the mutex.
            '
            Dim user As String = Environment.UserDomainName _ 
                & "\" & Environment.UserName
            Dim mSec As New MutexSecurity()

            Dim rule As New MutexAccessRule(user, _
                MutexRights.Synchronize Or MutexRights.Modify, _
                AccessControlType.Deny)
            mSec.AddAccessRule(rule)

            rule = New MutexAccessRule(user, _
                MutexRights.ReadPermissions Or _
                MutexRights.ChangePermissions, _
                AccessControlType.Allow)
            mSec.AddAccessRule(rule)

            ' Create a Mutex object that represents the system
            ' mutex named by the constant 'mutexName', with
            ' initial ownership for this thread, and with the
            ' specified security access. The Boolean value that 
            ' indicates creation of the underlying system object
            ' is placed in mutexWasCreated.
            '
            m = New Mutex(True, mutexName, mutexWasCreated, mSec)

            ' If the named system mutex was created, it can be
            ' used by the current instance of this program, even 
            ' though the current user is denied access. The current
            ' program owns the mutex. Otherwise, exit the program.
            ' 
            If mutexWasCreated Then
                Console.WriteLine("Created the mutex.")
            Else
                Console.WriteLine("Unable to create the mutex.")
                Return
            End If

        ElseIf unauthorized Then

            ' Open the mutex to read and change the access control
            ' security. The access control security defined above
            ' allows the current user to do this.
            '
            Try
                m = Mutex.OpenExisting(mutexName, _
                    MutexRights.ReadPermissions Or _
                    MutexRights.ChangePermissions)

                ' Get the current ACL. This requires 
                ' MutexRights.ReadPermissions.
                Dim mSec As MutexSecurity = m.GetAccessControl()
                
                Dim user As String = Environment.UserDomainName _ 
                    & "\" & Environment.UserName

                ' First, the rule that denied the current user 
                ' the right to enter and release the mutex must
                ' be removed.
                Dim rule As New MutexAccessRule(user, _
                    MutexRights.Synchronize Or MutexRights.Modify, _
                    AccessControlType.Deny)
                mSec.RemoveAccessRule(rule)

                ' Now grant the user the correct rights.
                ' 
                rule = New MutexAccessRule(user, _
                    MutexRights.Synchronize Or MutexRights.Modify, _
                    AccessControlType.Allow)
                mSec.AddAccessRule(rule)

                ' Update the ACL. This requires
                ' MutexRights.ChangePermissions.
                m.SetAccessControl(mSec)

                Console.WriteLine("Updated mutex security.")

                ' Open the mutex with (MutexRights.Synchronize 
                ' Or MutexRights.Modify), the rights required to
                ' enter and release the mutex.
                '
                m = Mutex.OpenExisting(mutexName)

            Catch ex As UnauthorizedAccessException
                Console.WriteLine("Unable to change permissions: {0}", _
                    ex.Message)
                Return
            End Try

        End If

        ' If this program created the mutex, it already owns
        ' the mutex.
        '
        If Not mutexWasCreated Then
            ' Enter the mutex, and hold it until the program
            ' exits.
            '
            Try
                Console.WriteLine("Wait for the mutex.")
                m.WaitOne()
                Console.WriteLine("Entered the mutex.")
            Catch ex As UnauthorizedAccessException
                Console.WriteLine("Unauthorized access: {0}", _
                    ex.Message)
            End Try
        End If

        Console.WriteLine("Press the Enter key to exit.")
        Console.ReadLine()
        m.ReleaseMutex()
        m.Dispose()
    End Sub 
End Class

Uwagi

Element name może mieć prefiks Global\ lub Local\ określać przestrzeń nazw. Po określeniu Global przestrzeni nazw obiekt synchronizacji może być współużytkowany z dowolnymi procesami w systemie. Po określeniu Local przestrzeni nazw, która jest również wartością domyślną, gdy nie określono przestrzeni nazw, obiekt synchronizacji może być współużytkowany z procesami w tej samej sesji. W systemie Windows sesja jest sesją logowania, a usługi są zwykle uruchamiane w innej sesji nieinterakcyjnej. W systemach operacyjnych przypominających system Unix każda powłoka ma własną sesję. Obiekty synchronizacji lokalnej sesji mogą być odpowiednie do synchronizacji między procesami z relacją nadrzędną/podrzędną, w której wszystkie są uruchamiane w tej samej sesji. Aby uzyskać więcej informacji na temat nazw obiektów synchronizacji w systemie Windows, zobacz Nazwy obiektów.

name Jeśli element jest podany, a obiekt synchronizacji żądanego typu już istnieje w przestrzeni nazw, używany jest istniejący obiekt synchronizacji. Jeśli obiekt synchronizacji innego typu już istnieje w przestrzeni nazw, WaitHandleCannotBeOpenedException zgłaszany jest obiekt . W przeciwnym razie zostanie utworzony nowy obiekt synchronizacji.

Jeśli name nie null jest i initiallyOwned jest true, wywołujący wątek jest właścicielem nazwanego mutex tylko wtedy, gdy createdNew jest true po wywołaniu. W przeciwnym razie wątek może zażądać mutex, wywołując metodę WaitOne .

Użyj tego konstruktora, aby zastosować zabezpieczenia kontroli dostępu do nazwanego mutexu systemowego podczas jego tworzenia, uniemożliwiając przejęcie kontroli nad mutexem przez inny kod.

Ten konstruktor inicjuje Mutex obiekt reprezentujący nazwany mutex systemowy. Można utworzyć wiele Mutex obiektów reprezentujących ten sam nazwany system mutex.

Jeśli nazwany mutex systemu nie istnieje, zostanie utworzony z określonymi zabezpieczeniami kontroli dostępu. Jeśli istnieje nazwany mutex, określone zabezpieczenia kontroli dostępu są ignorowane.

Uwaga

Obiekt wywołujący ma pełną kontrolę nad nowo utworzonym Mutex obiektem, nawet jeśli mutexSecurity odmówi lub nie udzieli niektórych praw dostępu bieżącemu użytkownikowi. Jeśli jednak bieżący użytkownik próbuje uzyskać inny Mutex obiekt reprezentujący ten sam nazwany mutex, przy użyciu konstruktora lub OpenExisting metody, stosowane są zabezpieczenia kontroli dostępu systemu Windows.

Jeśli nazwany mutex został już utworzony z zabezpieczeniami kontroli dostępu, a obiekt wywołujący nie ma MutexRights.FullControl, zgłaszany jest wyjątek. Aby otworzyć istniejący nazwany mutex z uprawnieniami wymaganymi tylko do synchronizowania działań wątku, zobacz metodę OpenExisting .

Jeśli określisz null ciąg lub ciąg pusty dla name, zostanie utworzony lokalny mutex, tak jakby został wywołany Mutex(Boolean) konstruktor. W takim przypadku createdNew wartość to zawsze true.

Ponieważ są one ogólnosystemowe, nazwane mutexes mogą służyć do koordynowania użycia zasobów przez granice procesów.

Uwaga

Na serwerze z uruchomionymi usługami terminali nazwany mutex systemu może mieć dwa poziomy widoczności. Jeśli nazwa zaczyna się od prefiksu Global\, mutex jest widoczny we wszystkich sesjach serwera terminali. Jeśli nazwa zaczyna się od prefiksu Local\, mutex jest widoczny tylko w sesji serwera terminali, w której został utworzony. W takim przypadku oddzielny mutex o tej samej nazwie może istnieć w każdej z pozostałych sesji serwera terminali na serwerze. Jeśli nie określisz prefiksu podczas tworzenia nazwanego mutexu, przyjmuje prefiks Local\. W sesji serwera terminalu dwa elementy mutex, których nazwy różnią się tylko ich prefiksami, są oddzielnymi mutexami, a oba są widoczne dla wszystkich procesów w sesji serwera terminalu. Oznacza to, że nazwy Global\ prefiksów i Local\ opisują zakres nazwy mutex względem sesji serwera terminali, a nie względem procesów.

Przestroga

Domyślnie nazwany mutex nie jest ograniczony do użytkownika, który go utworzył. Inni użytkownicy mogą być w stanie otworzyć i użyć mutex, w tym zakłócać działanie mutex, wprowadzając mutex i nie zamykając go. Aby ograniczyć dostęp do określonych użytkowników, możesz przekazać element MutexSecurity podczas tworzenia nazwanego mutexu. Unikaj używania nazwanych mutexes bez ograniczeń dostępu w systemach, które mogą mieć niezaufanych użytkowników z uruchomionym kodem.

Ukośnik odwrotny (\) jest zastrzeżonym znakiem w nazwie mutex. Nie należy używać ukośnika odwrotnego (\) w nazwie mutex z wyjątkiem określonej w notatce dotyczącej używania mutexes w sesjach serwera terminali. DirectoryNotFoundException W przeciwnym razie może zostać zgłoszony błąd, mimo że nazwa mutex reprezentuje istniejący plik.

Dotyczy