Semaphore Konstruktory
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.
Inicjuje nowe wystąpienie klasy Semaphore.
Przeciążenia
Semaphore(Int32, Int32) |
Inicjuje Semaphore nowe wystąpienie klasy, określając początkową liczbę wpisów i maksymalną liczbę równoczesnych wpisów. |
Semaphore(Int32, Int32, String) |
Inicjuje nowe wystąpienie Semaphore klasy, określając początkową liczbę wpisów i maksymalną liczbę równoczesnych 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ę 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. |
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. |
Semaphore(Int32, Int32)
- Źródło:
- Semaphore.cs
- Źródło:
- Semaphore.cs
- Źródło:
- Semaphore.cs
Inicjuje Semaphore nowe wystąpienie klasy, określając początkową liczbę wpisów i maksymalną liczbę równoczesnych 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. 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, co pozwala trzem wątkom wejść do 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, aby zwolnić semafor. Przy każdym wydaniu semafora jest wyświetlana 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, gdy bieżący wątek został wywołany WaitOne (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ę równoczesnych 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 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.
Wyjątki
initialCount
wartość jest większa niż maximumCount
.
-lub-
Tylko program .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
W poniższym przykładzie kodu pokazano zachowanie procesów krzyżowych nazwanego semafora. Przykład tworzy nazwany semafor 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 reprezentujący nazwany semafor systemowy. Można utworzyć wiele Semaphore obiektów, które reprezentują ten sam nazwany semafor systemowy.
Element name
może mieć prefiks Global\
lub Local\
określać przestrzeń nazw. Po określeniu Global
przestrzeni nazw obiekt synchronizacji może być współużytkowany z dowolnymi procesami w systemie. Po określeniu Local
przestrzeni nazw, która jest również wartością domyślną, gdy nie określono przestrzeni nazw, obiekt synchronizacji może być współużytkowany z procesami w tej samej sesji. W systemie Windows sesja jest sesją logowania, a usługi są zwykle uruchamiane w innej sesji nieinterakcyjnej. W systemach operacyjnych przypominających system Unix każda powłoka ma własną sesję. Obiekty synchronizacji lokalnej sesji mogą być odpowiednie do synchronizacji między procesami z relacją nadrzędną/podrzędną, w której wszystkie są uruchamiane w tej samej sesji. Aby uzyskać więcej informacji na temat nazw obiektów synchronizacji w systemie Windows, zobacz Nazwy obiektów.
name
Jeśli element jest podany, a obiekt synchronizacji żądanego typu już istnieje w przestrzeni nazw, używany jest istniejący obiekt synchronizacji. Jeśli obiekt synchronizacji innego typu już istnieje w przestrzeni nazw, WaitHandleCannotBeOpenedException
zgłaszany jest obiekt . W przeciwnym razie zostanie utworzony nowy obiekt synchronizacji.
Jeśli 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. Jeśli musisz określić, czy został utworzony nazwany semafor systemowy, zamiast tego 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 nazwany semafor systemowy jest tworzony, efekt jest taki sam, jak w przypadku, gdy bieżący wątek miał wywołanie WaitOne (maximumCount
minus initialCount
) razy. Jednak przy tym przeciążeniu konstruktora nie ma możliwości określenia, czy został utworzony nazwany semafor systemowy.
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) .
Ponieważ nazwane semafory 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 nazwany semafor i zgłasza wyjątek, jeśli semafor systemu 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ć 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)
- Ź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 program .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
W poniższym przykładzie kodu pokazano zachowanie procesów krzyżowych nazwanego semafora. W przykładzie tworzony jest 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
parametr ma false
wartość , 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 true
wartość , 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ę 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.
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 program .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 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.
Ten konstruktor inicjuje Semaphore obiekt, który reprezentuje nazwany semafor systemowy. Można utworzyć wiele Semaphore obiektów reprezentujących ten sam semafor systemowy.
Jeśli nazwany semafor systemowy nie istnieje, zostanie utworzony z określonymi zabezpieczeniami kontroli dostępu. Jeśli istnieje nazwany semafor, 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
odmawia lub nie udziela niektórych praw dostępu do bieżącego użytkownika. Jeśli jednak bieżący użytkownik próbuje uzyskać inny Semaphore obiekt reprezentujący ten sam nazwany semafor, przy użyciu konstruktora lub OpenExisting metody, zastosowano 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 i initialCount
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 ten konstruktor.
Jeśli initialCount
wartość jest mniejsza niż maximumCount
, i createdNew
jest true
, efekt jest taki sam, jak w przypadku wywołania WaitOne bieżącego wątku (maximumCount
minus initialCount
) razy.
Jeśli określisz null
lub pusty ciąg dla name
polecenia , zostanie utworzony lokalny semafor, tak jakby został wywołany przeciążenie konstruktora Semaphore(Int32, Int32) . W tym przypadku createdNew
zawsze true
jest to .
Ponieważ nazwane semaphores 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ć 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 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.