Semaphore Classe

Definizione

Limita il numero di thread che possono accedere simultaneamente a una risorsa o a un pool di risorse.

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
Ereditarietà
Semaphore
Ereditarietà
Attributi

Esempio

Nell'esempio di codice seguente viene creato un semaforo con un conteggio massimo di tre e un conteggio iniziale pari a zero. L'esempio avvia cinque thread, che bloccano l'attesa del semaforo. Il thread principale usa l'overload del Release(Int32) metodo per aumentare il numero di semafori al massimo, consentendo a tre thread di immettere il semaforo. Ogni thread usa il Thread.Sleep metodo per attendere un secondo, simulare il lavoro e quindi chiama l'overload del Release() metodo per rilasciare il semaforo. Ogni volta che viene rilasciato il semaforo, viene visualizzato il conteggio del semaforo precedente. I messaggi della console tengono traccia dell'uso del semaforo. L'intervallo di lavoro simulato viene aumentato leggermente per ogni thread, per semplificare la lettura dell'output.

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

Commenti

Usare la classe per controllare l'accesso Semaphore a un pool di risorse. I thread immettono il semaforo chiamando il WaitOne metodo , ereditato dalla WaitHandle classe e rilasciando il semaforo chiamando il Release metodo .

Il conteggio su un semaforo viene decrementato ogni volta che un thread entra nel semaforo e incrementato quando un thread rilascia il semaforo. Quando il conteggio è zero, le richieste successive si bloccano fino a quando altri thread non rilasciano il semaforo. Quando tutti i thread hanno rilasciato il semaforo, il conteggio è al valore massimo specificato al momento della creazione del semaforo.

Non esiste un ordine garantito, ad esempio FIFO o LIFO, in cui i thread bloccati immettono il semaforo.

Un thread può immettere più volte il semaforo chiamando ripetutamente il WaitOne metodo . Per rilasciare alcune o tutte queste voci, il thread può chiamare l'overload del metodo senza Release() parametri più volte oppure può chiamare l'overload del Release(Int32) metodo che specifica il numero di voci da rilasciare.

La Semaphore classe non applica l'identità del thread alle chiamate a WaitOne o Release. È responsabilità del programmatore assicurarsi che i thread non rilascino il semaforo troppe volte. Si supponga, ad esempio, che un semaforo abbia un conteggio massimo di due e che il thread A e il thread B entrino entrambi nel semaforo. Se un errore di programmazione nel thread B lo chiama Release due volte, entrambe le chiamate hanno esito positivo. Il conteggio sul semaforo è pieno e, quando il thread A infine chiama Release, viene generata un'eccezione SemaphoreFullException.

I semafori sono di due tipi: semafori locali e semafori di sistema denominati. Se si crea un oggetto usando un Semaphore costruttore che accetta un nome, viene associato a un semaforo del sistema operativo di tale nome. I semafori di sistema denominati sono visibili in tutto il sistema operativo e possono essere usati per sincronizzare le attività dei processi. È possibile creare più Semaphore oggetti che rappresentano lo stesso semaforo di sistema denominato ed è possibile usare il OpenExisting metodo per aprire un semaforo di sistema denominato esistente.

Un semaforo locale esiste solo all'interno del processo. Può essere usato da qualsiasi thread nel processo che ha un riferimento all'oggetto locale Semaphore . Ogni Semaphore oggetto è un semaforo locale separato.

Caution

Per impostazione predefinita, un semaforo denominato non è limitato all'utente che lo ha creato. Altri utenti possono essere in grado di aprire e usare il semaforo, incluso l'interferimento con il semaforo acquisendo il semaforo più volte e non rilasciandolo. Per limitare l'accesso a utenti specifici, è possibile usare un overload del costruttore o SemaphoreAcl passare un SemaphoreSecurity oggetto durante la creazione del semaforo denominato. Evitare di usare semafori denominati senza restrizioni di accesso nei sistemi che potrebbero avere utenti non attendibili che eseguono codice.

Costruttori

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

Inizializza una nuova istanza della Semaphore classe , specificando il numero iniziale di voci e il numero massimo di voci simultanee, specificando facoltativamente il nome di un oggetto semaforo di sistema, specificando una variabile che riceve un valore che indica se è stato creato un nuovo semaforo di sistema e specificando il controllo di accesso di sicurezza per il semaforo di sistema.

Semaphore(Int32, Int32, String, Boolean)

Inizializza una nuova istanza della Semaphore classe , specificando il numero iniziale di voci e il numero massimo di voci simultanee, specificando facoltativamente il nome di un oggetto semaforo di sistema e specificando una variabile che riceve un valore che indica se è stato creato un nuovo semaforo di sistema.

Semaphore(Int32, Int32, String, NamedWaitHandleOptions, Boolean)

Inizializza una nuova istanza della Semaphore classe , specificando il numero iniziale di voci e il numero massimo di voci simultanee, specificando facoltativamente il nome di un oggetto semaforo di sistema e le opzioni per impostare l'ambito utente e l'accesso all'ambito sessione e specificando una variabile che riceve un valore che indica se è stato creato un nuovo semaforo di sistema.

Semaphore(Int32, Int32, String, NamedWaitHandleOptions)

Inizializza una nuova istanza della Semaphore classe , specificando il numero iniziale di voci e il numero massimo di voci simultanee e, facoltativamente, specificando il nome di un oggetto semaforo di sistema e le opzioni per impostare l'ambito utente e l'accesso all'ambito sessione.

Semaphore(Int32, Int32, String)

Inizializza una nuova istanza della Semaphore classe , specificando il numero iniziale di voci e il numero massimo di voci simultanee e, facoltativamente, specificando il nome di un oggetto semaforo di sistema.

Semaphore(Int32, Int32)

Inizializza una nuova istanza della Semaphore classe , specificando il numero iniziale di voci e il numero massimo di voci simultanee.

Campi

Nome Descrizione
WaitTimeout

Indica che si è verificato un timeout di un'operazione WaitAny(WaitHandle[], Int32, Boolean) prima che uno degli handle di attesa sia stato segnalato. Questo campo è costante.

(Ereditato da WaitHandle)

Proprietà

Nome Descrizione
Handle
Obsoleti.
Obsoleti.

Ottiene o imposta l'handle nativo del sistema operativo.

(Ereditato da WaitHandle)
SafeWaitHandle

Ottiene o imposta l'handle nativo del sistema operativo.

(Ereditato da WaitHandle)

Metodi

Nome Descrizione
Close()

Rilascia tutte le risorse contenute nell'oggetto corrente WaitHandle.

(Ereditato da WaitHandle)
CreateObjRef(Type)

Crea un oggetto che contiene tutte le informazioni pertinenti necessarie per generare un proxy utilizzato per comunicare con un oggetto remoto.

(Ereditato da MarshalByRefObject)
Dispose()

Rilascia tutte le risorse usate dall'istanza corrente della WaitHandle classe .

(Ereditato da WaitHandle)
Dispose(Boolean)

In caso di override in una classe derivata, rilascia le risorse non gestite usate da WaitHandlee, facoltativamente, rilascia le risorse gestite.

(Ereditato da WaitHandle)
Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

(Ereditato da Object)
GetAccessControl()

Ottiene la sicurezza del controllo di accesso per un semaforo di sistema denominato.

GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetLifetimeService()
Obsoleti.

Recupera l'oggetto servizio di durata corrente che controlla i criteri di durata per questa istanza.

(Ereditato da MarshalByRefObject)
GetType()

Ottiene il Type dell'istanza corrente.

(Ereditato da Object)
InitializeLifetimeService()
Obsoleti.

Ottiene un oggetto servizio di durata per controllare i criteri di durata per questa istanza.

(Ereditato da MarshalByRefObject)
MemberwiseClone()

Crea una copia superficiale del Objectcorrente.

(Ereditato da Object)
MemberwiseClone(Boolean)

Crea una copia superficiale dell'oggetto corrente MarshalByRefObject .

(Ereditato da MarshalByRefObject)
OpenExisting(String, NamedWaitHandleOptions)

Apre il semaforo denominato specificato, se già esistente. Se le opzioni sono impostate solo sull'utente corrente, i controlli di accesso dell'oggetto vengono verificati per l'utente chiamante.

OpenExisting(String, SemaphoreRights)

Apre il semaforo denominato specificato, se già esistente, con l'accesso di sicurezza desiderato.

OpenExisting(String)

Apre il semaforo denominato specificato, se già esistente.

Release()

Esce dal semaforo e restituisce il conteggio precedente.

Release(Int32)

Esce dal semaforo un numero specificato di volte e restituisce il conteggio precedente.

SetAccessControl(SemaphoreSecurity)

Imposta la sicurezza del controllo di accesso per un semaforo di sistema denominato.

ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)
TryOpenExisting(String, NamedWaitHandleOptions, Semaphore)

Apre il semaforo denominato specificato, se già esistente, e restituisce un valore che indica se l'operazione ha avuto esito positivo. Se le opzioni sono impostate solo sull'utente corrente, i controlli di accesso dell'oggetto vengono verificati per l'utente chiamante.

TryOpenExisting(String, Semaphore)

Apre il semaforo denominato specificato, se già esistente, e restituisce un valore che indica se l'operazione ha avuto esito positivo.

TryOpenExisting(String, SemaphoreRights, Semaphore)

Apre il semaforo denominato specificato, se già esistente, con l'accesso di sicurezza desiderato e restituisce un valore che indica se l'operazione è riuscita.

WaitOne()

Blocca il thread corrente fino a quando l'oggetto corrente WaitHandle non riceve un segnale.

(Ereditato da WaitHandle)
WaitOne(Int32, Boolean)

Blocca il thread corrente fino a quando l'oggetto corrente WaitHandle non riceve un segnale, utilizzando un intero con segno a 32 bit per specificare l'intervallo di tempo e specificando se uscire dal dominio di sincronizzazione prima dell'attesa.

(Ereditato da WaitHandle)
WaitOne(Int32)

Blocca il thread corrente fino a quando l'oggetto corrente WaitHandle non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo in millisecondi.

(Ereditato da WaitHandle)
WaitOne(TimeSpan, Boolean)

Blocca il thread corrente fino a quando l'istanza corrente non riceve un segnale, utilizzando un TimeSpan oggetto per specificare l'intervallo di tempo e specificando se uscire dal dominio di sincronizzazione prima dell'attesa.

(Ereditato da WaitHandle)
WaitOne(TimeSpan)

Blocca il thread corrente fino a quando l'istanza corrente non riceve un segnale, usando un TimeSpan oggetto per specificare l'intervallo di tempo.

(Ereditato da WaitHandle)

Implementazioni dell'interfaccia esplicita

Nome Descrizione
IDisposable.Dispose()

Questa API supporta l'infrastruttura del prodotto e non è previsto che venga usata direttamente dal codice.

Rilascia tutte le risorse usate da WaitHandle.

(Ereditato da WaitHandle)

Metodi di estensione

Nome Descrizione
GetAccessControl(Semaphore)

Restituisce i descrittori di sicurezza per l'oggetto specificato semaphore.

GetSafeWaitHandle(WaitHandle)

Ottiene l'handle sicuro per un handle di attesa del sistema operativo nativo.

SetAccessControl(Semaphore, SemaphoreSecurity)

Imposta i descrittori di sicurezza per il semaforo specificato.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Imposta un handle sicuro per un handle di attesa del sistema operativo nativo.

Si applica a

Thread safety

Questo tipo è thread-safe.

Vedi anche