Udostępnij za pośrednictwem


Semaphore Klasa

Definicja

Ogranicza liczbę wątków, które mogą jednocześnie uzyskiwać dostęp do zasobu lub puli zasobów.

public ref class Semaphore sealed : System::Threading::WaitHandle
public sealed class Semaphore : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class Semaphore : System.Threading.WaitHandle
type Semaphore = class
    inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(false)>]
type Semaphore = class
    inherit WaitHandle
Public NotInheritable Class Semaphore
Inherits WaitHandle
Dziedziczenie
Semaphore
Dziedziczenie
Atrybuty

Przykłady

Poniższy przykład kodu 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

Semaphore Użyj klasy , aby kontrolować dostęp do puli zasobów. Wątki wchodzą w semafor, wywołując WaitOne metodę, która jest dziedziczona z WaitHandle klasy, i zwalniają semafor, wywołując metodę Release .

Liczba semaforów jest dekrementowana za każdym razem, gdy wątek wchodzi do semafora i zwiększa się, gdy wątek zwalnia semafor. Gdy liczba jest równa zero, kolejne żądania blokują, dopóki inne wątki nie zwolnią semafora. Gdy wszystkie wątki zwolniły semafor, liczba jest w maksymalnej wartości określonej podczas tworzenia semafora.

Nie ma gwarantowanej kolejności, takiej jak FIFO lub LIFO, w której zablokowane wątki wchodzą do semafora.

Wątek może wielokrotnie wprowadzać semafor, wywołując metodę WaitOne wielokrotnie. Aby zwolnić niektóre lub wszystkie te wpisy, wątek może wywołać przeciążenie metody bez Release() parametrów wiele razy lub wywołać Release(Int32) przeciążenie metody, które określa liczbę wpisów do wydania.

Klasa Semaphore nie wymusza tożsamości wątku na wywołaniach lub ReleaseWaitOne . Jest to odpowiedzialność programisty, aby upewnić się, że wątki nie zwalniają semafora zbyt wiele razy. Załóżmy na przykład, że semafor ma maksymalną liczbę dwóch, a ten wątek A i wątek B wchodzą w semafor. Jeśli błąd programowania w wątku B powoduje dwukrotne wywołanie Release , oba wywołania kończą się powodzeniem. Liczba semaforów jest pełna, a gdy wątek A w końcu wywołuje Release, SemaphoreFullException jest zgłaszany.

Semaphores są dwóch typów: lokalne semafory i nazwane semaphores systemu. Jeśli utworzysz Semaphore obiekt przy użyciu konstruktora, który akceptuje nazwę, jest on skojarzony z semaforem systemu operacyjnego tej nazwy. Nazwane semafory systemu są widoczne w całym systemie operacyjnym i mogą służyć do synchronizowania działań procesów. Można utworzyć wiele Semaphore obiektów reprezentujących ten sam semafor systemowy, a za pomocą OpenExisting metody można otworzyć istniejący semafor systemowy.

Lokalny semafor istnieje tylko w ramach procesu. Może być używany przez dowolny wątek w procesie, który ma odwołanie do obiektu lokalnego Semaphore . Każdy Semaphore obiekt jest oddzielnym semaforem lokalnym.

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.

Konstruktory

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.

Pola

WaitTimeout

Wskazuje, że WaitAny(WaitHandle[], Int32, Boolean) upłynął limit czasu operacji, zanim którykolwiek z uchwytów oczekiwania został zasygnalizowany. To pole jest stałe.

(Odziedziczone po WaitHandle)

Właściwości

Handle
Przestarzałe.
Przestarzałe.

Pobiera lub ustawia natywny uchwyt systemu operacyjnego.

(Odziedziczone po WaitHandle)
SafeWaitHandle

Pobiera lub ustawia natywny uchwyt systemu operacyjnego.

(Odziedziczone po WaitHandle)

Metody

Close()

Zwalnia wszystkie zasoby przechowywane przez bieżący WaitHandleelement .

(Odziedziczone po WaitHandle)
CreateObjRef(Type)

Tworzy obiekt zawierający wszystkie istotne informacje wymagane do wygenerowania serwera proxy używanego do komunikowania się z obiektem zdalnym.

(Odziedziczone po MarshalByRefObject)
Dispose()

Zwalnia wszystkie zasoby używane przez bieżące wystąpienie klasy WaitHandle.

(Odziedziczone po WaitHandle)
Dispose(Boolean)

Po zastąpieniu w klasie pochodnej zwalnia niezarządzane zasoby używane przez WaitHandleprogram i opcjonalnie zwalnia zarządzane zasoby.

(Odziedziczone po WaitHandle)
Equals(Object)

Określa, czy dany obiekt jest taki sam, jak bieżący obiekt.

(Odziedziczone po Object)
GetAccessControl()

Pobiera zabezpieczenia kontroli dostępu dla nazwanego semafora systemowego.

GetHashCode()

Służy jako domyślna funkcja skrótu.

(Odziedziczone po Object)
GetLifetimeService()
Przestarzałe.

Pobiera bieżący obiekt usługi okresu istnienia, który kontroluje zasady okresu istnienia dla tego wystąpienia.

(Odziedziczone po MarshalByRefObject)
GetType()

Type Pobiera bieżące wystąpienie.

(Odziedziczone po Object)
InitializeLifetimeService()
Przestarzałe.

Uzyskuje obiekt usługi okresu istnienia, aby kontrolować zasady okresu istnienia dla tego wystąpienia.

(Odziedziczone po MarshalByRefObject)
MemberwiseClone()

Tworzy płytkią kopię bieżącego Objectelementu .

(Odziedziczone po Object)
MemberwiseClone(Boolean)

Tworzy płytkią kopię bieżącego MarshalByRefObject obiektu.

(Odziedziczone po MarshalByRefObject)
OpenExisting(String)

Otwiera określony semafor o nazwie , jeśli już istnieje.

OpenExisting(String, SemaphoreRights)

Otwiera określony semafor o nazwie , jeśli już istnieje, z żądanym dostępem do zabezpieczeń.

Release()

Zamyka semafor i zwraca poprzednią liczbę.

Release(Int32)

Zamyka semafor określoną liczbę razy i zwraca poprzednią liczbę.

SetAccessControl(SemaphoreSecurity)

Ustawia zabezpieczenia kontroli dostępu dla nazwanego semafora systemowego.

ToString()

Zwraca ciąg reprezentujący bieżący obiekt.

(Odziedziczone po Object)
TryOpenExisting(String, Semaphore)

Otwiera określony semafor o nazwie , jeśli już istnieje i zwraca wartość wskazującą, czy operacja zakończyła się pomyślnie.

TryOpenExisting(String, SemaphoreRights, Semaphore)

Otwiera określony semafor o nazwie , jeśli już istnieje, z żądanym dostępem zabezpieczeń i zwraca wartość wskazującą, czy operacja zakończyła się pomyślnie.

WaitOne()

Blokuje bieżący wątek, dopóki bieżący WaitHandle nie otrzyma sygnału.

(Odziedziczone po WaitHandle)
WaitOne(Int32)

Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu w milisekundach.

(Odziedziczone po WaitHandle)
WaitOne(Int32, Boolean)

Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

(Odziedziczone po WaitHandle)
WaitOne(TimeSpan)

Blokuje bieżący wątek, dopóki bieżące wystąpienie nie otrzyma sygnału przy użyciu elementu , TimeSpan aby określić interwał czasu.

(Odziedziczone po WaitHandle)
WaitOne(TimeSpan, Boolean)

Blokuje bieżący wątek, dopóki bieżące wystąpienie nie otrzyma sygnału, przy użyciu elementu , TimeSpan aby określić interwał czasu i określić, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

(Odziedziczone po WaitHandle)

Jawne implementacje interfejsu

IDisposable.Dispose()

Ten interfejs API obsługuje infrastrukturę produktu i nie jest przeznaczony do użycia bezpośrednio z poziomu kodu.

Zwalnia wszelkie zasoby używane przez element WaitHandle.

(Odziedziczone po WaitHandle)

Metody rozszerzania

GetAccessControl(Semaphore)

Zwraca deskryptory zabezpieczeń dla określonego semaphoreelementu .

SetAccessControl(Semaphore, SemaphoreSecurity)

Ustawia deskryptory zabezpieczeń dla określonego semafora.

GetSafeWaitHandle(WaitHandle)

Pobiera bezpieczny uchwyt dla natywnego uchwytu oczekiwania systemu operacyjnego.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Ustawia bezpieczny uchwyt dla natywnego uchwytu oczekiwania systemu operacyjnego.

Dotyczy

Bezpieczeństwo wątkowe

Ten typ jest bezpieczny wątkowo.

Zobacz też