Semaphore Klasa
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
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
- Dziedziczenie
- Atrybuty
Przykłady
Poniższy przykład kodu tworzy semafor z maksymalną liczbą trzech i początkową liczbą zera. W przykładzie uruchamia się 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 trzy wątki wejścia semafora. Każdy wątek używa Thread.Sleep metody , aby poczekać na jedną sekundę, zasymulować pracę, a następnie wywołuje Release() przeciążenie metody w celu zwolnienia semafora. Za każdym razem, gdy semafor jest zwalniany, wyświetlana jest 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;
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
Użyj klasy , Semaphore aby kontrolować dostęp do puli zasobów. Wątki wprowadzają 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 na 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 może wywołać Release(Int32) przeciążenie metody, która określa liczbę wpisów do wydania.
Klasa Semaphore nie wymusza tożsamości wątku na wywołaniach do WaitOne lub Release. Obowiązkiem programisty jest zapewnienie, że wątki nie zwalniają semafora zbyt wiele razy. Załóżmy na przykład, że semafor ma maksymalną wartość dwa i że zarówno wątek A, jak i wątek B wchodzą do semafora. Jeśli błąd programowania w wątku B powoduje dwukrotne wywołanie Release , oba wywołania kończą się powodzeniem. Licznik semafora jest pełny, a gdy wątek A ostatecznie wywołuje Release, SemaphoreFullException jest wyrzucany.
Semafory mają dwa typy: semafory lokalne i nazwane semafory systemowe. Jeśli utworzysz obiekt przy użyciu konstruktora Semaphore , który akceptuje nazwę, jest 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 o tej samej nazwie i można użyć OpenExisting metody , aby otworzyć istniejący semaphor systemowy.
Lokalny semafor istnieje tylko w ramach procesu. Może być używany przez dowolny wątek w procesie, który zawiera odwołanie do obiektu lokalnego Semaphore . Każdy Semaphore obiekt jest oddzielnym semaforem lokalnym.
Caution
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 do systemów, które mogą mieć niezaufanych użytkowników z uruchomionym kodem.
Konstruktory
| Nazwa | Opis |
|---|---|
| Semaphore(Int32, Int32, String, Boolean, SemaphoreSecurity) |
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, 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. |
| 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 został utworzony nowy semafor systemu. |
| Semaphore(Int32, Int32, String, NamedWaitHandleOptions, 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 opcji ustawiania dostępu do zakresu użytkownika i zakresu sesji oraz określając zmienną, która odbiera wartość wskazującą, czy został utworzony nowy semafor systemu. |
| Semaphore(Int32, Int32, String, NamedWaitHandleOptions) |
Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę wpisów współbieżnych oraz opcjonalnie określając nazwę obiektu semafora systemowego i opcji ustawiania dostępu do zakresu użytkownika i zakresu sesji. |
| Semaphore(Int32, Int32, String) |
Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę wpisów współbieżnych oraz opcjonalnie określając nazwę obiektu semafora systemowego. |
| Semaphore(Int32, Int32) |
Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę równoczesnych wpisów. |
Pola
| Nazwa | Opis |
|---|---|
| WaitTimeout |
Wskazuje, że WaitAny(WaitHandle[], Int32, Boolean) upłynął limit czasu operacji, zanim zostanie zasygnalizowana którakolwiek z dojść oczekiwania. To pole jest stałe. (Odziedziczone po WaitHandle) |
Właściwości
| Nazwa | Opis |
|---|---|
| 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
| Nazwa | Opis |
|---|---|
| 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 WaitHandle klasy. (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 określony obiekt jest równy bieżącemu obiektowi. (Odziedziczone po Object) |
| GetAccessControl() |
Pobiera zabezpieczenia kontroli dostępu dla nazwanego semafora systemu. |
| 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() |
Pobiera Type bieżącego wystąpienia. (Odziedziczone po Object) |
| InitializeLifetimeService() |
Przestarzałe.
Uzyskuje obiekt usługi okresu istnienia w celu kontrolowania zasad okresu istnienia dla tego wystąpienia. (Odziedziczone po MarshalByRefObject) |
| MemberwiseClone() |
Tworzy płytkią kopię bieżącego Object. (Odziedziczone po Object) |
| MemberwiseClone(Boolean) |
Tworzy płytkią kopię bieżącego MarshalByRefObject obiektu. (Odziedziczone po MarshalByRefObject) |
| OpenExisting(String, NamedWaitHandleOptions) |
Otwiera określony semafor o nazwie, jeśli już istnieje. Jeśli opcje są ustawione tylko dla bieżącego użytkownika, kontrole dostępu obiektu są weryfikowane dla użytkownika wywołującego. |
| OpenExisting(String, SemaphoreRights) |
Otwiera określony semafor o nazwie, jeśli już istnieje, z żądanym dostępem zabezpieczeń. |
| OpenExisting(String) |
Otwiera określony semafor o nazwie, jeśli już istnieje. |
| 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 systemu. |
| ToString() |
Zwraca ciąg reprezentujący bieżący obiekt. (Odziedziczone po Object) |
| TryOpenExisting(String, NamedWaitHandleOptions, Semaphore) |
Otwiera określony semafor o nazwie, jeśli już istnieje i zwraca wartość wskazującą, czy operacja zakończyła się pomyślnie. Jeśli opcje są ustawione tylko dla bieżącego użytkownika, kontrole dostępu obiektu są weryfikowane dla użytkownika wywołującego. |
| 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 nie WaitHandle otrzyma sygnału. (Odziedziczone po WaitHandle) |
| WaitOne(Int32, Boolean) |
Blokuje bieżący wątek do momentu WaitHandle odebrania sygnału przy użyciu 32-bitowej liczby całkowitej ze znakiem, aby określić interwał czasu i określić, czy zakończyć domenę synchronizacji przed oczekiwaniem. (Odziedziczone po WaitHandle) |
| WaitOne(Int32) |
Blokuje bieżący wątek do momentu WaitHandle odebrania sygnału przy użyciu 32-bitowej liczby całkowitej ze znakiem w celu określenia interwału czasu w milisekundach. (Odziedziczone po WaitHandle) |
| WaitOne(TimeSpan, Boolean) |
Blokuje bieżący wątek, dopóki bieżące wystąpienie nie odbierze sygnału, używając parametru , TimeSpan aby określić interwał czasu i określić, czy należy zamknąć domenę synchronizacji przed oczekiwaniem. (Odziedziczone po WaitHandle) |
| WaitOne(TimeSpan) |
Blokuje bieżący wątek do momentu odebrania sygnału przez bieżące wystąpienie przy użyciu parametru , TimeSpan aby określić interwał czasu. (Odziedziczone po WaitHandle) |
Jawne implementacje interfejsu
| Nazwa | Opis |
|---|---|
| IDisposable.Dispose() |
Ten interfejs API obsługuje infrastrukturę produktu i nie jest przeznaczony do użycia bezpośrednio z poziomu kodu. Zwalnia wszystkie zasoby używane przez program WaitHandle. (Odziedziczone po WaitHandle) |
Metody rozszerzania
| Nazwa | Opis |
|---|---|
| GetAccessControl(Semaphore) |
Zwraca deskryptory zabezpieczeń dla określonego |
| GetSafeWaitHandle(WaitHandle) |
Pobiera bezpieczny uchwyt dla natywnego uchwytu oczekiwania systemu operacyjnego. |
| SetAccessControl(Semaphore, SemaphoreSecurity) |
Ustawia deskryptory zabezpieczeń dla określonego semafora. |
| SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
Ustawia bezpieczny uchwyt dla natywnego uchwytu oczekiwania systemu operacyjnego. |
Dotyczy
Bezpieczeństwo wątkowe
Ten typ jest bezpieczny wątkiem.