Semaphore Konstruktory

Definicja

Inicjuje nowe wystąpienie klasy Semaphore.

Przeciążenia

Semaphore(Int32, Int32)

Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę współbieżnych wpisów.

Semaphore(Int32, Int32, String)

Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę współbieżnych wpisów oraz opcjonalnie określając nazwę obiektu semafora systemowego.

Semaphore(Int32, Int32, String, Boolean)

Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę wpisów współbieżnych, opcjonalnie określając nazwę obiektu semafora systemowego i określając zmienną, która odbiera wartość wskazującą, czy utworzono nowy semafor systemowy.

Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity)

Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę współbieżnych wpisów, opcjonalnie określając nazwę obiektu semafora systemowego, określając zmienną, która odbiera wartość wskazującą, czy utworzono nowy semafor systemu, i określając kontrolę dostępu zabezpieczeń dla semafora systemu.

Semaphore(Int32, Int32)

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

Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę współbieżnych wpisów.

public:
 Semaphore(int initialCount, int maximumCount);
public Semaphore (int initialCount, int maximumCount);
new System.Threading.Semaphore : int * int -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer)

Parametry

initialCount
Int32

Początkowa liczba żądań semafora, które można udzielić współbieżnie.

maximumCount
Int32

Maksymalna liczba żądań semafora, które można udzielić współbieżnie.

Wyjątki

initialCount wartość jest większa niż maximumCount.

maximumCount wartość jest mniejsza niż 1.

-lub-

initialCount wartość jest mniejsza niż 0.

Przykłady

Poniższy przykład tworzy semafor z maksymalną liczbą trzech i początkową liczbą zera. Przykład uruchamia pięć wątków, które blokują oczekiwanie na semafor. Główny wątek używa Release(Int32) przeciążenia metody, aby zwiększyć liczbę semaforów do maksymalnej, umożliwiając trzem wątkom wprowadzanie semafora. Każdy wątek używa Thread.Sleep metody do oczekiwania na jedną sekundę, do symulowania pracy, a następnie wywołuje Release() przeciążenie metody, aby zwolnić semafor. Za każdym razem, gdy semafor zostanie wydany, zostanie wyświetlona poprzednia liczba semaforów. Komunikaty konsoli śledzą użycie semafora. Symulowany interwał pracy jest nieznacznie zwiększany dla każdego wątku, aby ułatwić odczytywanie danych wyjściowych.

#using <System.dll>
using namespace System;
using namespace System::Threading;

public ref class Example
{
private:
   // A semaphore that simulates a limited resource pool.
   //
   static Semaphore^ _pool;

   // A padding interval to make the output more orderly.
   static int _padding;

public:
   static void Main()
   {
      // Create a semaphore that can satisfy up to three
      // concurrent requests. Use an initial count of zero,
      // so that the entire semaphore count is initially
      // owned by the main program thread.
      //
      _pool = gcnew Semaphore( 0,3 );
      
      // Create and start five numbered threads.
      //
      for ( int i = 1; i <= 5; i++ )
      {
         Thread^ t = gcnew Thread(
            gcnew ParameterizedThreadStart( Worker ) );
         
         // Start the thread, passing the number.
         //
         t->Start( i );
      }
      
      // Wait for half a second, to allow all the
      // threads to start and to block on the semaphore.
      //
      Thread::Sleep( 500 );
      
      // The main thread starts out holding the entire
      // semaphore count. Calling Release(3) brings the
      // semaphore count back to its maximum value, and
      // allows the waiting threads to enter the semaphore,
      // up to three at a time.
      //
      Console::WriteLine( L"Main thread calls Release(3)." );
      _pool->Release( 3 );

      Console::WriteLine( L"Main thread exits." );
   }

private:
   static void Worker( Object^ num )
   {
      // Each worker thread begins by requesting the
      // semaphore.
      Console::WriteLine( L"Thread {0} begins and waits for the semaphore.", num );
      _pool->WaitOne();
      
      // A padding interval to make the output more orderly.
      int padding = Interlocked::Add( _padding, 100 );

      Console::WriteLine( L"Thread {0} enters the semaphore.", num );
      
      // The thread's "work" consists of sleeping for
      // about a second. Each thread "works" a little
      // longer, just to make the output more orderly.
      //
      Thread::Sleep( 1000 + padding );

      Console::WriteLine( L"Thread {0} releases the semaphore.", num );
      Console::WriteLine( L"Thread {0} previous semaphore count: {1}",
         num, _pool->Release() );
   }
};
using System;
using System.Threading;

public class Example
{
    // A semaphore that simulates a limited resource pool.
    //
    private static Semaphore _pool;

    // A padding interval to make the output more orderly.
    private static int _padding;

    public static void Main()
    {
        // Create a semaphore that can satisfy up to three
        // concurrent requests. Use an initial count of zero,
        // so that the entire semaphore count is initially
        // owned by the main program thread.
        //
        _pool = new Semaphore(initialCount: 0, maximumCount: 3);

        // Create and start five numbered threads. 
        //
        for(int i = 1; i <= 5; i++)
        {
            Thread t = new Thread(new ParameterizedThreadStart(Worker));

            // Start the thread, passing the number.
            //
            t.Start(i);
        }

        // Wait for half a second, to allow all the
        // threads to start and to block on the semaphore.
        //
        Thread.Sleep(500);

        // The main thread starts out holding the entire
        // semaphore count. Calling Release(3) brings the 
        // semaphore count back to its maximum value, and
        // allows the waiting threads to enter the semaphore,
        // up to three at a time.
        //
        Console.WriteLine("Main thread calls Release(3).");
        _pool.Release(releaseCount: 3);

        Console.WriteLine("Main thread exits.");
    }

    private static void Worker(object num)
    {
        // Each worker thread begins by requesting the
        // semaphore.
        Console.WriteLine("Thread {0} begins " +
            "and waits for the semaphore.", num);
        _pool.WaitOne();

        // A padding interval to make the output more orderly.
        int padding = Interlocked.Add(ref _padding, 100);

        Console.WriteLine("Thread {0} enters the semaphore.", num);
        
        // The thread's "work" consists of sleeping for 
        // about a second. Each thread "works" a little 
        // longer, just to make the output more orderly.
        //
        Thread.Sleep(1000 + padding);

        Console.WriteLine("Thread {0} releases the semaphore.", num);
        Console.WriteLine("Thread {0} previous semaphore count: {1}",
            num, _pool.Release());
    }
}
Imports System.Threading

Public Class Example

    ' A semaphore that simulates a limited resource pool.
    '
    Private Shared _pool As Semaphore

    ' A padding interval to make the output more orderly.
    Private Shared _padding As Integer

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a semaphore that can satisfy up to three
        ' concurrent requests. Use an initial count of zero,
        ' so that the entire semaphore count is initially
        ' owned by the main program thread.
        '
        _pool = New Semaphore(0, 3)

        ' Create and start five numbered threads. 
        '
        For i As Integer = 1 To 5
            Dim t As New Thread(New ParameterizedThreadStart(AddressOf Worker))
            'Dim t As New Thread(AddressOf Worker)

            ' Start the thread, passing the number.
            '
            t.Start(i)
        Next i

        ' Wait for half a second, to allow all the
        ' threads to start and to block on the semaphore.
        '
        Thread.Sleep(500)

        ' The main thread starts out holding the entire
        ' semaphore count. Calling Release(3) brings the 
        ' semaphore count back to its maximum value, and
        ' allows the waiting threads to enter the semaphore,
        ' up to three at a time.
        '
        Console.WriteLine("Main thread calls Release(3).")
        _pool.Release(3)

        Console.WriteLine("Main thread exits.")
    End Sub

    Private Shared Sub Worker(ByVal num As Object)
        ' Each worker thread begins by requesting the
        ' semaphore.
        Console.WriteLine("Thread {0} begins " _
            & "and waits for the semaphore.", num)
        _pool.WaitOne()

        ' A padding interval to make the output more orderly.
        Dim padding As Integer = Interlocked.Add(_padding, 100)

        Console.WriteLine("Thread {0} enters the semaphore.", num)
        
        ' The thread's "work" consists of sleeping for 
        ' about a second. Each thread "works" a little 
        ' longer, just to make the output more orderly.
        '
        Thread.Sleep(1000 + padding)

        Console.WriteLine("Thread {0} releases the semaphore.", num)
        Console.WriteLine("Thread {0} previous semaphore count: {1}", _
            num, _
            _pool.Release())
    End Sub
End Class

Uwagi

Ten konstruktor inicjuje nienazwany semafor. Wszystkie wątki używające wystąpienia takiego semafora muszą mieć odwołania do wystąpienia.

Jeśli initialCount wartość jest mniejsza niż maximumCount, efekt jest taki sam, jak w przypadku wywołania WaitOne bieżącego wątku (maximumCount minus initialCount) razy. Jeśli nie chcesz zarezerwować żadnych wpisów dla wątku, który tworzy semafor, użyj tej samej liczby dla maximumCount i initialCount.

Zobacz też

Dotyczy

Semaphore(Int32, Int32, String)

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

Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę współbieżnych wpisów oraz opcjonalnie określając nazwę obiektu semafora systemowego.

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name);
public Semaphore (int initialCount, int maximumCount, string name);
public Semaphore (int initialCount, int maximumCount, string? name);
new System.Threading.Semaphore : int * int * string -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String)

Parametry

initialCount
Int32

Początkowa liczba żądań semafora, które można udzielić współbieżnie.

maximumCount
Int32

Maksymalna liczba żądań semafora, które można udzielić współbieżnie.

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 służyć 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 wykluczeniu przestrzeni nazw musi być prawidłową nazwą pliku.

Wyjątki

initialCount wartość jest większa niż maximumCount.

-lub-

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

maximumCount wartość jest mniejsza niż 1.

-lub-

initialCount wartość jest mniejsza niż 0.

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 nazwy i typowe prefiksy "Global\" i "Local\" są uwzględniane wielkość liter.

-lub-

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

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

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

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

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

Przykłady

Poniższy przykład kodu przedstawia zachowanie między procesami nazwanego semafora. W przykładzie jest tworzony nazwany semaphor z maksymalną liczbą pięciu i początkową liczbą pięciu. Program wykonuje trzy wywołania WaitOne metody . W związku z tym, jeśli uruchomisz skompilowany przykład z dwóch okien poleceń, druga kopia zablokuje trzecie wywołanie metody .WaitOne Zwolnij co najmniej jeden wpis w pierwszej kopii programu, aby odblokować drugi.

#using <System.dll>
using namespace System;
using namespace System::Threading;

public ref class Example
{
public:
   static void main()
   {
      // Create a Semaphore object that represents the named
      // system semaphore "SemaphoreExample3". The semaphore has a
      // maximum count of five. The initial count is also five.
      // There is no point in using a smaller initial count,
      // because the initial count is not used if this program
      // doesn't create the named system semaphore, and with
      // this method overload there is no way to tell. Thus, this
      // program assumes that it is competing with other
      // programs for the semaphore.
      //
      Semaphore^ sem = gcnew Semaphore( 5,5,L"SemaphoreExample3" );
      
      // Attempt to enter the semaphore three times. If another
      // copy of this program is already running, only the first
      // two requests can be satisfied. The third blocks. Note
      // that in a real application, timeouts should be used
      // on the WaitOne calls, to avoid deadlocks.
      //
      sem->WaitOne();
      Console::WriteLine( L"Entered the semaphore once." );
      sem->WaitOne();
      Console::WriteLine( L"Entered the semaphore twice." );
      sem->WaitOne();
      Console::WriteLine( L"Entered the semaphore three times." );
      
      // The thread executing this program has entered the
      // semaphore three times. If a second copy of the program
      // is run, it will block until this program releases the
      // semaphore at least once.
      //
      Console::WriteLine( L"Enter the number of times to call Release." );
      int n;
      if ( Int32::TryParse( Console::ReadLine(),n ) )
      {
         sem->Release( n );
      }

      int remaining = 3 - n;
      if ( remaining > 0 )
      {
         Console::WriteLine( L"Press Enter to release the remaining "
         L"count ({0}) and exit the program.", remaining );
         Console::ReadLine();
         sem->Release( remaining );
      }
   }
};
using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // Create a Semaphore object that represents the named 
        // system semaphore "SemaphoreExample3". The semaphore has a
        // maximum count of five. The initial count is also five. 
        // There is no point in using a smaller initial count,
        // because the initial count is not used if this program
        // doesn't create the named system semaphore, and with 
        // this method overload there is no way to tell. Thus, this
        // program assumes that it is competing with other
        // programs for the semaphore.
        //
        Semaphore sem = new Semaphore(5, 5, "SemaphoreExample3");

        // Attempt to enter the semaphore three times. If another 
        // copy of this program is already running, only the first
        // two requests can be satisfied. The third blocks. Note 
        // that in a real application, timeouts should be used
        // on the WaitOne calls, to avoid deadlocks.
        //
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore once.");
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore twice.");
        sem.WaitOne();
        Console.WriteLine("Entered the semaphore three times.");

        // The thread executing this program has entered the 
        // semaphore three times. If a second copy of the program
        // is run, it will block until this program releases the 
        // semaphore at least once.
        //
        Console.WriteLine("Enter the number of times to call Release.");
        int n;
        if (int.TryParse(Console.ReadLine(), out n))
        {
            sem.Release(n);
        }

        int remaining = 3 - n;
        if (remaining > 0)
        {
            Console.WriteLine("Press Enter to release the remaining " +
                "count ({0}) and exit the program.", remaining);
            Console.ReadLine();
            sem.Release(remaining);
        }
    }
}
Imports System.Threading

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' Create a Semaphore object that represents the named 
        ' system semaphore "SemaphoreExample3". The semaphore has a
        ' maximum count of five. The initial count is also five. 
        ' There is no point in using a smaller initial count,
        ' because the initial count is not used if this program
        ' doesn't create the named system semaphore, and with 
        ' this method overload there is no way to tell. Thus, this
        ' program assumes that it is competing with other
        ' programs for the semaphore.
        '
        Dim sem As New Semaphore(5, 5, "SemaphoreExample3")

        ' Attempt to enter the semaphore three times. If another 
        ' copy of this program is already running, only the first
        ' two requests can be satisfied. The third blocks. Note 
        ' that in a real application, timeouts should be used
        ' on the WaitOne calls, to avoid deadlocks.
        '
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore once.")
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore twice.")
        sem.WaitOne()
        Console.WriteLine("Entered the semaphore three times.")

        ' The thread executing this program has entered the 
        ' semaphore three times. If a second copy of the program
        ' is run, it will block until this program releases the 
        ' semaphore at least once.
        '
        Console.WriteLine("Enter the number of times to call Release.")
        Dim n As Integer
        If Integer.TryParse(Console.ReadLine(), n) Then
            sem.Release(n)
        End If

        Dim remaining As Integer = 3 - n
        If (remaining) > 0 Then
            Console.WriteLine("Press Enter to release the remaining " _
                & "count ({0}) and exit the program.", remaining)
            Console.ReadLine()
            sem.Release(remaining)
        End If

    End Sub 
End Class

Uwagi

Ten konstruktor inicjuje Semaphore obiekt, który reprezentuje nazwany semafor systemowy. Można utworzyć wiele Semaphore obiektów reprezentujących ten sam semafor systemowy.

Element name może być poprzedzony prefiksem Global\ lub Local\ w celu określenia przestrzeni 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ż domyślna, 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 podobnych do systemu Unix każda powłoka ma własną sesję. Obiekty synchronizacji lokalnej sesji mogą być odpowiednie do synchronizowania procesów 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 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 jest zgłaszany. W przeciwnym razie zostanie utworzony nowy obiekt synchronizacji.

Jeśli nazwany semafor systemowy nie istnieje, jest tworzony z początkową liczbą i maksymalną liczbą określoną przez initialCount i maximumCount. Jeśli nazwany semafor systemowy już istnieje i initialCountmaximumCount nie są używane, chociaż nieprawidłowe wartości nadal powodują wyjątki. Jeśli musisz określić, czy został utworzony nazwany semafor systemowy, użyj przeciążenia konstruktora Semaphore(Int32, Int32, String, Boolean) .

Ważne

W przypadku użycia tego przeciążenia konstruktora zalecaną praktyką jest określenie tej samej liczby dla initialCount i maximumCount. Jeśli initialCount wartość jest mniejsza niż maximumCount, a tworzony jest nazwany semafor systemowy, efekt jest taki sam, jak w przypadku wywołania WaitOne bieżącego wątku (maximumCount minus initialCount) razy. Jednak przy przeciążeniu tego konstruktora nie ma możliwości określenia, czy został utworzony nazwany semafor systemowy.

Jeśli określisz null lub pusty ciąg dla namepolecenia , zostanie utworzony lokalny semafor, tak jakby został wywołany przeciążenie konstruktora Semaphore(Int32, Int32) .

Ponieważ nazwane semaphores są widoczne w całym systemie operacyjnym, mogą służyć do koordynowania użycia zasobów przez granice procesu.

Jeśli chcesz dowiedzieć się, czy istnieje nazwany semafor systemowy, użyj OpenExisting metody . Metoda OpenExisting próbuje otworzyć istniejący semafor o nazwie i zgłasza wyjątek, jeśli semafor systemowy nie istnieje.

Przestroga

Domyślnie nazwany semafor nie jest ograniczony do użytkownika, który go utworzył. Inni użytkownicy mogą być w stanie otworzyć i użyć semaforu, w tym zakłócać semafor przez uzyskanie semafora wiele razy i nie zwalniając go. Aby ograniczyć dostęp do określonych użytkowników, możesz użyć przeciążenia konstruktora lub SemaphoreAcl przekazać SemaphoreSecurity element podczas tworzenia nazwanego semafora. Unikaj używania nazwanych semaphores bez ograniczeń dostępu w systemach, które mogą mieć niezaufanych użytkowników z uruchomionym kodem.

Zobacz też

Dotyczy

Semaphore(Int32, Int32, String, Boolean)

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

Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę równoczesnych wpisów, opcjonalnie określając nazwę obiektu semafora systemowego i określając zmienną, która odbiera wartość wskazującą, czy został utworzony nowy semafor systemu.

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew);
public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew);
public Semaphore (int initialCount, int maximumCount, string? name, out bool createdNew);
new System.Threading.Semaphore : int * int * string * bool -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, ByRef createdNew As Boolean)

Parametry

initialCount
Int32

Początkowa liczba żądań semafora, które mogą być spełnione jednocześnie.

maximumCount
Int32

Maksymalna liczba żądań semafora, który może być spełniony jednocześnie.

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ść , zawiera true , czy został utworzony lokalny semafor (czyli jeśli name jest null lub jest pusty ciąg) lub jeśli określony nazwany semafor systemowy został utworzony; false jeśli określony nazwany semafor systemowy już istniał. Ten parametr jest przekazywany jako niezainicjowany.

Wyjątki

initialCount wartość jest większa niż maximumCount.

-lub-

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

maximumCount wartość jest mniejsza niż 1.

-lub-

initialCount wartość jest mniejsza niż 0.

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 semafor istnieje i ma zabezpieczenia kontroli dostępu, a 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ę.

Przykłady

Poniższy przykład kodu przedstawia zachowanie między procesami nazwanego semafora. Przykład tworzy nazwany semafor z maksymalną liczbą pięciu i początkową liczbą dwóch. Oznacza to, że rezerwuje trzy wpisy dla wątku, który wywołuje konstruktor. Jeśli createNew jest to false, program wykonuje trzy wywołania WaitOne metody . W związku z tym, jeśli uruchomisz skompilowany przykład z dwóch okien poleceń, druga kopia zablokuje trzecie wywołanie metody .WaitOne Zwolnij co najmniej jeden wpis w pierwszej kopii programu, aby odblokować drugi.

#using <System.dll>
using namespace System;
using namespace System::Threading;

public ref class Example
{
public:
   static void main()
   {
      // The value of this variable is set by the semaphore
      // constructor. It is true if the named system semaphore was
      // created, and false if the named semaphore already existed.
      //
      bool semaphoreWasCreated;
      
      // Create a Semaphore object that represents the named
      // system semaphore "SemaphoreExample". The semaphore has a
      // maximum count of five, and an initial count of two. The
      // Boolean value that indicates creation of the underlying
      // system object is placed in semaphoreWasCreated.
      //
      Semaphore^ sem = gcnew Semaphore( 2,5,L"SemaphoreExample",
         semaphoreWasCreated );
      if ( semaphoreWasCreated )
      {
         // If the named system semaphore was created, its count is
         // set to the initial count requested in the constructor.
         // In effect, the current thread has entered the semaphore
         // three times.
         //
         Console::WriteLine( L"Entered the semaphore three times." );
      }
      else
      {
         // If the named system semaphore was not created,
         // attempt to enter it three times. If another copy of
         // this program is already running, only the first two
         // requests can be satisfied. The third blocks.
         //
         sem->WaitOne();
         Console::WriteLine( L"Entered the semaphore once." );
         sem->WaitOne();
         Console::WriteLine( L"Entered the semaphore twice." );
         sem->WaitOne();
         Console::WriteLine( L"Entered the semaphore three times." );
      }
      
      // The thread executing this program has entered the
      // semaphore three times. If a second copy of the program
      // is run, it will block until this program releases the
      // semaphore at least once.
      //
      Console::WriteLine( L"Enter the number of times to call Release." );
      int n;
      if ( Int32::TryParse( Console::ReadLine(), n ) )
      {
         sem->Release( n );
      }

      int remaining = 3 - n;
      if ( remaining > 0 )
      {
         Console::WriteLine( L"Press Enter to release the remaining "
         L"count ({0}) and exit the program.", remaining );
         Console::ReadLine();
         sem->Release( remaining );
      }
   }
};
using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // The value of this variable is set by the semaphore
        // constructor. It is true if the named system semaphore was
        // created, and false if the named semaphore already existed.
        //
        bool semaphoreWasCreated;

        // Create a Semaphore object that represents the named 
        // system semaphore "SemaphoreExample". The semaphore has a
        // maximum count of five, and an initial count of two. The
        // Boolean value that indicates creation of the underlying 
        // system object is placed in semaphoreWasCreated.
        //
        Semaphore sem = new Semaphore(2, 5, "SemaphoreExample", 
            out semaphoreWasCreated);

        if (semaphoreWasCreated)
        {
            // If the named system semaphore was created, its count is
            // set to the initial count requested in the constructor.
            // In effect, the current thread has entered the semaphore
            // three times.
            // 
            Console.WriteLine("Entered the semaphore three times.");
        }
        else
        {      
            // If the named system semaphore was not created,  
            // attempt to enter it three times. If another copy of
            // this program is already running, only the first two
            // requests can be satisfied. The third blocks.
            //
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore once.");
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore twice.");
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore three times.");
        }

        // The thread executing this program has entered the 
        // semaphore three times. If a second copy of the program
        // is run, it will block until this program releases the 
        // semaphore at least once.
        //
        Console.WriteLine("Enter the number of times to call Release.");
        int n;
        if (int.TryParse(Console.ReadLine(), out n))
        {
            sem.Release(n);
        }

        int remaining = 3 - n;
        if (remaining > 0)
        {
            Console.WriteLine("Press Enter to release the remaining " +
                "count ({0}) and exit the program.", remaining);
            Console.ReadLine();
            sem.Release(remaining);
        }
    } 
}
Imports System.Threading

Public Class Example

    <MTAThread> _
    Public Shared Sub Main()
        ' The value of this variable is set by the semaphore
        ' constructor. It is True if the named system semaphore was
        ' created, and False if the named semaphore already existed.
        '
        Dim semaphoreWasCreated As Boolean

        ' Create a Semaphore object that represents the named 
        ' system semaphore "SemaphoreExample". The semaphore has a
        ' maximum count of five, and an initial count of two. The
        ' Boolean value that indicates creation of the underlying 
        ' system object is placed in semaphoreWasCreated.
        '
        Dim sem As New Semaphore(2, 5, "SemaphoreExample", _
            semaphoreWasCreated)

        If semaphoreWasCreated Then
            ' If the named system semaphore was created, its count is
            ' set to the initial count requested in the constructor.
            ' In effect, the current thread has entered the semaphore
            ' three times.
            ' 
            Console.WriteLine("Entered the semaphore three times.")
        Else
            ' If the named system semaphore was not created,  
            ' attempt to enter it three times. If another copy of
            ' this program is already running, only the first two
            ' requests can be satisfied. The third blocks.
            '
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore once.")
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore twice.")
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore three times.")
        End If

        ' The thread executing this program has entered the 
        ' semaphore three times. If a second copy of the program
        ' is run, it will block until this program releases the 
        ' semaphore at least once.
        '
        Console.WriteLine("Enter the number of times to call Release.")
        Dim n As Integer
        If Integer.TryParse(Console.ReadLine(), n) Then
            sem.Release(n)
        End If

        Dim remaining As Integer = 3 - n
        If (remaining) > 0 Then
            Console.WriteLine("Press Enter to release the remaining " _
                & "count ({0}) and exit the program.", remaining)
            Console.ReadLine()
            sem.Release(remaining)
        End If

    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.

Ten konstruktor inicjuje Semaphore obiekt reprezentujący nazwany semafor systemowy. Można utworzyć wiele Semaphore obiektów, które reprezentują ten sam nazwany semafor systemowy.

Jeśli nazwany semafor systemowy nie istnieje, jest tworzony z początkową liczbą i maksymalną liczbą określoną przez initialCount i maximumCount. Jeśli nazwany semafor systemowy już istnieje initialCount i maximumCount nie są używane, chociaż nieprawidłowe wartości nadal powodują wyjątki. Służy createdNew do określania, czy został utworzony semafor systemu.

Jeśli initialCount wartość jest mniejsza niż maximumCount, i createdNew ma truewartość , efekt jest taki sam, jak w przypadku, gdy bieżący wątek miał wywołaną WaitOne wartość (maximumCount minus initialCount) razy.

Jeśli określisz null lub pusty ciąg dla name, zostanie utworzony lokalny semafor, tak jakby został wywołany przeciążenie konstruktora Semaphore(Int32, Int32) . W takim przypadku createdNew wartość to zawsze true.

Ponieważ nazwane semafory są widoczne w całym systemie operacyjnym, mogą służyć do koordynowania użycia zasobów przez granice procesu.

Przestroga

Domyślnie nazwany semafor nie jest ograniczony do użytkownika, który go utworzył. Inni użytkownicy mogą być w stanie otworzyć i użyć semafora, w tym zakłócać semafor, uzyskując semafor wiele razy i nie zwalniając go. Aby ograniczyć dostęp do określonych użytkowników, można użyć przeciążenia konstruktora lub SemaphoreAcl przekazać SemaphoreSecurity element podczas tworzenia nazwanego semafora. Unikaj używania nazwanych semaforów bez ograniczeń dostępu w systemach, które mogą mieć niezaufanych użytkowników z uruchomionym kodem.

Zobacz też

Dotyczy

Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity)

Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę równoczesnych wpisów, opcjonalnie określając nazwę obiektu semafora systemowego, określając zmienną, która odbiera wartość wskazującą, czy został utworzony nowy semafor systemu i określając kontrolę dostępu zabezpieczeń dla semafora systemu.

public:
 Semaphore(int initialCount, int maximumCount, System::String ^ name, [Runtime::InteropServices::Out] bool % createdNew, System::Security::AccessControl::SemaphoreSecurity ^ semaphoreSecurity);
public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew, System.Security.AccessControl.SemaphoreSecurity semaphoreSecurity);
new System.Threading.Semaphore : int * int * string * bool * System.Security.AccessControl.SemaphoreSecurity -> System.Threading.Semaphore
Public Sub New (initialCount As Integer, maximumCount As Integer, name As String, ByRef createdNew As Boolean, semaphoreSecurity As SemaphoreSecurity)

Parametry

initialCount
Int32

Początkowa liczba żądań semafora, które mogą być spełnione jednocześnie.

maximumCount
Int32

Maksymalna liczba żądań semafora, który może być spełniony jednocześnie.

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ść , zawiera true , czy został utworzony lokalny semafor (czyli jeśli name jest null lub jest pusty ciąg) lub jeśli określony nazwany semafor systemowy został utworzony; false jeśli określony nazwany semafor systemowy już istniał. Ten parametr jest przekazywany jako niezainicjowany.

semaphoreSecurity
SemaphoreSecurity

SemaphoreSecurity Obiekt reprezentujący zabezpieczenia kontroli dostępu, które mają być stosowane do nazwanego semafora systemu.

Wyjątki

initialCount wartość jest większa niż maximumCount.

-lub-

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

maximumCount wartość jest mniejsza niż 1.

-lub-

initialCount wartość jest mniejsza niż 0.

Nazwany semafor istnieje i ma zabezpieczenia kontroli dostępu, a 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ę.

Przykłady

W poniższym przykładzie kodu pokazano zachowanie procesu krzyżowego nazwanego semafora z zabezpieczeniami kontroli dostępu. W przykładzie użyto OpenExisting(String) przeciążenia metody do przetestowania istnienia nazwanego semafora. Jeśli semafor nie istnieje, jest tworzony z maksymalną liczbą dwóch i z zabezpieczeniami kontroli dostępu, które odmawia bieżącemu użytkownikowi prawa do korzystania z semafora, ale przyznaje prawo do odczytu i zmiany uprawnień do semafora. Jeśli uruchomisz skompilowany przykład z dwóch okien poleceń, druga kopia zgłosi wyjątek naruszenia dostępu dla wywołania OpenExisting(String) metody . Wyjątek zostanie przechwycony, a w przykładzie użyto OpenExisting(String, SemaphoreRights) przeciążenia metody, aby otworzyć semafor z prawami wymaganymi do odczytu i zmiany uprawnień.

Po zmianie uprawnień semafor jest otwierany z prawami wymaganymi do wprowadzenia i wydania. Jeśli uruchomisz skompilowany przykład z trzeciego okna polecenia, zostanie ono uruchomione przy użyciu nowych uprawnień.

#using <System.dll>
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^ semaphoreName = L"SemaphoreExample5";

      Semaphore^ sem = nullptr;
      bool doesNotExist = false;
      bool unauthorized = false;
      
      // Attempt to open the named semaphore.
      try
      {
         // Open the semaphore with (SemaphoreRights.Synchronize
         // | SemaphoreRights.Modify), to enter and release the
         // named semaphore.
         //
         sem = Semaphore::OpenExisting( semaphoreName );
      }
      catch ( WaitHandleCannotBeOpenedException^ ex ) 
      {
         Console::WriteLine( L"Semaphore does not exist." );
         doesNotExist = true;
      }
      catch ( UnauthorizedAccessException^ ex ) 
      {
         Console::WriteLine( L"Unauthorized access: {0}", ex->Message );
         unauthorized = true;
      }

      // There are three cases: (1) The semaphore does not exist.
      // (2) The semaphore exists, but the current user doesn't
      // have access. (3) The semaphore exists and the user has
      // access.
      //
      if ( doesNotExist )
      {
         // The semaphore does not exist, so create it.
         //
         // The value of this variable is set by the semaphore
         // constructor. It is true if the named system semaphore was
         // created, and false if the named semaphore already existed.
         //
         bool semaphoreWasCreated;
         
         // Create an access control list (ACL) that denies the
         // current user the right to enter or release the
         // semaphore, but allows the right to read and change
         // security information for the semaphore.
         //
         String^ user = String::Concat( Environment::UserDomainName,
            L"\\", Environment::UserName );
         SemaphoreSecurity^ semSec = gcnew SemaphoreSecurity;

         SemaphoreAccessRule^ rule = gcnew SemaphoreAccessRule( user,
            static_cast<SemaphoreRights>(
               SemaphoreRights::Synchronize |
               SemaphoreRights::Modify ),
            AccessControlType::Deny );
         semSec->AddAccessRule( rule );

         rule = gcnew SemaphoreAccessRule( user,
            static_cast<SemaphoreRights>(
               SemaphoreRights::ReadPermissions |
               SemaphoreRights::ChangePermissions ),
            AccessControlType::Allow );
         semSec->AddAccessRule( rule );
         
         // Create a Semaphore object that represents the system
         // semaphore named by the constant 'semaphoreName', with
         // maximum count three, initial count three, and the
         // specified security access. The Boolean value that
         // indicates creation of the underlying system object is
         // placed in semaphoreWasCreated.
         //
         sem = gcnew Semaphore( 3,3,semaphoreName,semaphoreWasCreated,semSec );
         
         // If the named system semaphore was created, it can be
         // used by the current instance of this program, even
         // though the current user is denied access. The current
         // program enters the semaphore. Otherwise, exit the
         // program.
         //
         if ( semaphoreWasCreated )
         {
            Console::WriteLine( L"Created the semaphore." );
         }
         else
         {
            Console::WriteLine( L"Unable to create the semaphore." );
            return;
         }

      }
      else if ( unauthorized )
      {
         // Open the semaphore to read and change the access
         // control security. The access control security defined
         // above allows the current user to do this.
         //
         try
         {
            sem = Semaphore::OpenExisting( semaphoreName,
               static_cast<SemaphoreRights>(
                  SemaphoreRights::ReadPermissions |
                  SemaphoreRights::ChangePermissions ));
            
            // Get the current ACL. This requires
            // SemaphoreRights.ReadPermissions.
            SemaphoreSecurity^ semSec = sem->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 semaphore must
            // be removed.
            SemaphoreAccessRule^ rule = gcnew SemaphoreAccessRule( user,
               static_cast<SemaphoreRights>(
                  SemaphoreRights::Synchronize |
                  SemaphoreRights::Modify ),
               AccessControlType::Deny );
            semSec->RemoveAccessRule( rule );
            
            // Now grant the user the correct rights.
            //
            rule = gcnew SemaphoreAccessRule( user,
               static_cast<SemaphoreRights>(
                  SemaphoreRights::Synchronize |
                  SemaphoreRights::Modify ),
               AccessControlType::Allow );
            semSec->AddAccessRule( rule );
            
            // Update the ACL. This requires
            // SemaphoreRights.ChangePermissions.
            sem->SetAccessControl( semSec );

            Console::WriteLine( L"Updated semaphore security." );
            
            // Open the semaphore with (SemaphoreRights.Synchronize
            // | SemaphoreRights.Modify), the rights required to
            // enter and release the semaphore.
            //
            sem = Semaphore::OpenExisting( semaphoreName );

         }
         catch ( UnauthorizedAccessException^ ex ) 
         {
            Console::WriteLine( L"Unable to change permissions: {0}", ex->Message );
            return;
         }
      }
      
      // Enter the semaphore, and hold it until the program
      // exits.
      //
      try
      {
         sem->WaitOne();
         Console::WriteLine( L"Entered the semaphore." );
         Console::WriteLine( L"Press the Enter key to exit." );
         Console::ReadLine();
         sem->Release();
      }
      catch ( UnauthorizedAccessException^ ex ) 
      {
         Console::WriteLine( L"Unauthorized access: {0}", ex->Message );
      }
   }
};
using System;
using System.Threading;
using System.Security.AccessControl;

internal class Example
{
    internal static void Main()
    {
        const string semaphoreName = "SemaphoreExample5";

        Semaphore sem = null;
        bool doesNotExist = false;
        bool unauthorized = false;

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

        // There are three cases: (1) The semaphore does not exist.
        // (2) The semaphore exists, but the current user doesn't 
        // have access. (3) The semaphore exists and the user has
        // access.
        //
        if (doesNotExist)
        {
            // The semaphore does not exist, so create it.
            //
            // The value of this variable is set by the semaphore
            // constructor. It is true if the named system semaphore was
            // created, and false if the named semaphore already existed.
            //
            bool semaphoreWasCreated;

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

            SemaphoreAccessRule rule = new SemaphoreAccessRule(
                user, 
                SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                AccessControlType.Deny);
            semSec.AddAccessRule(rule);

            rule = new SemaphoreAccessRule(
                user, 
                SemaphoreRights.ReadPermissions | SemaphoreRights.ChangePermissions,
                AccessControlType.Allow);
            semSec.AddAccessRule(rule);

            // Create a Semaphore object that represents the system
            // semaphore named by the constant 'semaphoreName', with
            // maximum count three, initial count three, and the
            // specified security access. The Boolean value that 
            // indicates creation of the underlying system object is
            // placed in semaphoreWasCreated.
            //
            sem = new Semaphore(3, 3, semaphoreName, 
                out semaphoreWasCreated, semSec);

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

                // Get the current ACL. This requires 
                // SemaphoreRights.ReadPermissions.
                SemaphoreSecurity semSec = sem.GetAccessControl();
                
                string user = Environment.UserDomainName + "\\" 
                    + Environment.UserName;

                // First, the rule that denied the current user 
                // the right to enter and release the semaphore must
                // be removed.
                SemaphoreAccessRule rule = new SemaphoreAccessRule(
                    user, 
                    SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                    AccessControlType.Deny);
                semSec.RemoveAccessRule(rule);

                // Now grant the user the correct rights.
                // 
                rule = new SemaphoreAccessRule(user, 
                     SemaphoreRights.Synchronize | SemaphoreRights.Modify, 
                     AccessControlType.Allow);
                semSec.AddAccessRule(rule);

                // Update the ACL. This requires
                // SemaphoreRights.ChangePermissions.
                sem.SetAccessControl(semSec);

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

                // Open the semaphore with (SemaphoreRights.Synchronize 
                // | SemaphoreRights.Modify), the rights required to
                // enter and release the semaphore.
                //
                sem = Semaphore.OpenExisting(semaphoreName);
            }
            catch(UnauthorizedAccessException ex)
            {
                Console.WriteLine("Unable to change permissions: {0}", ex.Message);
                return;
            }
        }

        // Enter the semaphore, and hold it until the program
        // exits.
        //
        try
        {
            sem.WaitOne();
            Console.WriteLine("Entered the semaphore.");
            Console.WriteLine("Press the Enter key to exit.");
            Console.ReadLine();
            sem.Release();
        }
        catch(UnauthorizedAccessException ex)
        {
            Console.WriteLine("Unauthorized access: {0}", ex.Message);
        }
    }
}
Imports System.Threading
Imports System.Security.AccessControl

Friend Class Example

    <MTAThread> _
    Friend Shared Sub Main()
        Const semaphoreName As String = "SemaphoreExample5"

        Dim sem As Semaphore = Nothing
        Dim doesNotExist as Boolean = False
        Dim unauthorized As Boolean = False

        ' Attempt to open the named semaphore.
        Try
            ' Open the semaphore with (SemaphoreRights.Synchronize
            ' Or SemaphoreRights.Modify), to enter and release the
            ' named semaphore.
            '
            sem = Semaphore.OpenExisting(semaphoreName)
        Catch ex As WaitHandleCannotBeOpenedException
            Console.WriteLine("Semaphore 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 semaphore does not exist.
        ' (2) The semaphore exists, but the current user doesn't 
        ' have access. (3) The semaphore exists and the user has
        ' access.
        '
        If doesNotExist Then
            ' The semaphore does not exist, so create it.
            '
            ' The value of this variable is set by the semaphore
            ' constructor. It is True if the named system semaphore was
            ' created, and False if the named semaphore already existed.
            '
            Dim semaphoreWasCreated As Boolean

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

            Dim rule As New SemaphoreAccessRule(user, _
                SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                AccessControlType.Deny)
            semSec.AddAccessRule(rule)

            rule = New SemaphoreAccessRule(user, _
                SemaphoreRights.ReadPermissions Or _
                SemaphoreRights.ChangePermissions, _
                AccessControlType.Allow)
            semSec.AddAccessRule(rule)

            ' Create a Semaphore object that represents the system
            ' semaphore named by the constant 'semaphoreName', with
            ' maximum count three, initial count three, and the
            ' specified security access. The Boolean value that 
            ' indicates creation of the underlying system object is
            ' placed in semaphoreWasCreated.
            '
            sem = New Semaphore(3, 3, semaphoreName, _
                semaphoreWasCreated, semSec)

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

        ElseIf unauthorized Then

            ' Open the semaphore to read and change the access
            ' control security. The access control security defined
            ' above allows the current user to do this.
            '
            Try
                sem = Semaphore.OpenExisting(semaphoreName, _
                    SemaphoreRights.ReadPermissions Or _
                    SemaphoreRights.ChangePermissions)

                ' Get the current ACL. This requires 
                ' SemaphoreRights.ReadPermissions.
                Dim semSec As SemaphoreSecurity = sem.GetAccessControl()
                
                Dim user As String = Environment.UserDomainName _ 
                    & "\" & Environment.UserName

                ' First, the rule that denied the current user 
                ' the right to enter and release the semaphore must
                ' be removed.
                Dim rule As New SemaphoreAccessRule(user, _
                    SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                    AccessControlType.Deny)
                semSec.RemoveAccessRule(rule)

                ' Now grant the user the correct rights.
                ' 
                rule = New SemaphoreAccessRule(user, _
                    SemaphoreRights.Synchronize Or SemaphoreRights.Modify, _
                    AccessControlType.Allow)
                semSec.AddAccessRule(rule)

                ' Update the ACL. This requires
                ' SemaphoreRights.ChangePermissions.
                sem.SetAccessControl(semSec)

                Console.WriteLine("Updated semaphore security.")

                ' Open the semaphore with (SemaphoreRights.Synchronize 
                ' Or SemaphoreRights.Modify), the rights required to
                ' enter and release the semaphore.
                '
                sem = Semaphore.OpenExisting(semaphoreName)

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

        End If

        ' Enter the semaphore, and hold it until the program
        ' exits.
        '
        Try
            sem.WaitOne()
            Console.WriteLine("Entered the semaphore.")
            Console.WriteLine("Press the Enter key to exit.")
            Console.ReadLine()
            sem.Release()
        Catch ex As UnauthorizedAccessException
            Console.WriteLine("Unauthorized access: {0}", _
                ex.Message)
        End Try
    End Sub 
End Class

Uwagi

Użyj tego konstruktora, aby zastosować zabezpieczenia kontroli dostępu do nazwanego semafora systemu podczas jego tworzenia, uniemożliwiając innego kodu przejęcie kontroli nad semaforem.

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.

Ten konstruktor inicjuje Semaphore obiekt reprezentujący nazwany semafor systemowy. Można utworzyć wiele Semaphore obiektów, które reprezentują ten sam nazwany semafor systemowy.

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

Uwaga

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

Jeśli nazwany semafor systemowy nie istnieje, jest tworzony z początkową liczbą i maksymalną liczbą określoną przez initialCount i maximumCount. Jeśli nazwany semafor systemowy już istnieje initialCount i maximumCount nie są używane, chociaż nieprawidłowe wartości nadal powodują wyjątki. Użyj parametru , createdNew aby określić, czy semafor systemowy został utworzony przez tego konstruktora.

Jeśli initialCount wartość jest mniejsza niż maximumCount, i createdNew ma truewartość , efekt jest taki sam, jak w przypadku, gdy bieżący wątek miał wywołaną WaitOne wartość (maximumCount minus initialCount) razy.

Jeśli określisz null lub pusty ciąg dla name, zostanie utworzony lokalny semafor, tak jakby został wywołany przeciążenie konstruktora Semaphore(Int32, Int32) . W takim przypadku createdNew wartość to zawsze true.

Ponieważ nazwane semafory są widoczne w całym systemie operacyjnym, mogą służyć do koordynowania użycia zasobów przez granice procesu.

Przestroga

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

Zobacz też

Dotyczy