Semaphore Classe

Definizione

Limita il numero di thread che possono accedere simultaneamente a una risorsa o a un pool di risorse.Limits the number of threads that can access a resource or pool of resources concurrently.

public ref class Semaphore sealed : System::Threading::WaitHandle
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class Semaphore : System.Threading.WaitHandle
type Semaphore = class
    inherit WaitHandle
Public NotInheritable Class Semaphore
Inherits WaitHandle
Ereditarietà
Attributi

Esempi

Nell'esempio di codice seguente viene creato un semaforo con un numero massimo di tre e un conteggio iniziale pari a zero.The following code example creates a semaphore with a maximum count of three and an initial count of zero. L'esempio avvia cinque thread, che bloccano l'attesa del semaforo.The example starts five threads, which block waiting for the semaphore. Il thread principale usa l' Release(Int32) overload del metodo per aumentare il numero di semafori al massimo, consentendo a tre thread di accedere al semaforo.The main thread uses the Release(Int32) method overload to increase the semaphore count to its maximum, allowing three threads to enter the semaphore. Ogni thread usa il Thread.Sleep metodo per attendere un secondo, per simulare il lavoro e quindi chiama l' Release() overload del metodo per rilasciare il semaforo.Each thread uses the Thread.Sleep method to wait for one second, to simulate work, and then calls the Release() method overload to release the semaphore. Ogni volta che viene rilasciato il semaforo, viene visualizzato il numero di semafori precedente.Each time the semaphore is released, the previous semaphore count is displayed. I messaggi della console tengono traccia dell'uso del semaforo.Console messages track semaphore use. L'intervallo di lavoro simulato viene leggermente aumentato per ogni thread, per semplificare la lettura dell'output.The simulated work interval is increased slightly for each thread, to make the output easier to read.

#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(0, 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(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

Utilizzare la Semaphore classe per controllare l'accesso a un pool di risorse.Use the Semaphore class to control access to a pool of resources. I thread entrano nel semaforo chiamando WaitOne il metodo, che viene ereditato WaitHandle dalla classe, e rilascia il semaforo chiamando il Release metodo.Threads enter the semaphore by calling the WaitOne method, which is inherited from the WaitHandle class, and release the semaphore by calling the Release method.

Il conteggio su un semaforo viene decrementato ogni volta che un thread entra nel semaforo e viene incrementato quando un thread rilascia il semaforo.The count on a semaphore is decremented each time a thread enters the semaphore, and incremented when a thread releases the semaphore. Quando il conteggio è pari a zero, le richieste successive vengono bloccate finché altri thread non rilasciano il semaforo.When the count is zero, subsequent requests block until other threads release the semaphore. Quando tutti i thread hanno rilasciato il semaforo, il conteggio corrisponde al valore massimo specificato al momento della creazione del semaforo.When all threads have released the semaphore, the count is at the maximum value specified when the semaphore was created.

Non esiste alcun ordine garantito, ad esempio FIFO o LIFO, in cui i thread bloccati entrano nel semaforo.There is no guaranteed order, such as FIFO or LIFO, in which blocked threads enter the semaphore.

Un thread può accedere al semaforo più volte, chiamando ripetutamente WaitOne il metodo.A thread can enter the semaphore multiple times, by calling the WaitOne method repeatedly. Per rilasciare alcune o tutte queste voci, il thread può chiamare l'overload del Release() metodo senza parametri più volte oppure può chiamare l' Release(Int32) overload del metodo che specifica il numero di voci da rilasciare.To release some or all of these entries, the thread can call the parameterless Release() method overload multiple times, or it can call the Release(Int32) method overload that specifies the number of entries to be released.

La Semaphore classe non impone l'identità del thread per le WaitOne chiamate Releasea o.The Semaphore class does not enforce thread identity on calls to WaitOne or Release. È responsabilità del programmatore garantire che i thread non rilascino il semaforo troppo spesso.It is the programmer's responsibility to ensure that threads do not release the semaphore too many times. Ad esempio, si consideri un semaforo con un conteggio massimo di due e il thread A e B accedano entrambi al semaforo.For example, suppose a semaphore has a maximum count of two, and that thread A and thread B both enter the semaphore. Se un errore di programmazione nel thread B ne causa la Release chiamata due volte, entrambe le chiamate hanno esito positivo.If a programming error in thread B causes it to call Release twice, both calls succeed. Il conteggio sul semaforo è completo e quando il thread A alla fine chiama Release, viene generata un'eccezione SemaphoreFullException.The count on the semaphore is full, and when thread A eventually calls Release, a SemaphoreFullException is thrown.

I semafori sono di due tipi: i semafori locali e i semafori di sistema denominati.Semaphores are of two types: local semaphores and named system semaphores. Se si crea un Semaphore oggetto usando un costruttore che accetta un nome, questo viene associato a un semaforo del sistema operativo con tale nome.If you create a Semaphore object using a constructor that accepts a name, it is associated with an operating-system semaphore of that name. I semafori di sistema denominati sono visibili in tutto il sistema operativo e possono essere usati per sincronizzare le attività dei processi.Named system semaphores are visible throughout the operating system, and can be used to synchronize the activities of processes. È 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.You can create multiple Semaphore objects that represent the same named system semaphore, and you can use the OpenExisting method to open an existing named system semaphore.

Un semaforo locale esiste solo nel processo.A local semaphore exists only within your process. Può essere usato da qualsiasi thread nel processo che abbia un riferimento all'oggetto Semaphore locale.It can be used by any thread in your process that has a reference to the local Semaphore object. Ogni Semaphore oggetto è un semaforo locale separato.Each Semaphore object is a separate local semaphore.

Costruttori

Semaphore(Int32, Int32)

Inizializza una nuova istanza della classe Semaphore, specificando il numero di voci iniziale e il numero massimo di voci contemporanei.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries.

Semaphore(Int32, Int32, String)

Inizializza una nuova istanza della classe Semaphore, specificando il numero di voci iniziale e il numero massimo di voci contemporanee, nonché indicando facoltativamente il nome di un oggetto semaforo di sistema.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, and optionally specifying the name of a system semaphore object.

Semaphore(Int32, Int32, String, Boolean)

Inizializza una nuova istanza della classe Semaphore, specificando il numero di accessi iniziale e il numero massimo di accessi contemporanei, indicando 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.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, optionally specifying the name of a system semaphore object, and specifying a variable that receives a value indicating whether a new system semaphore was created.

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

Inizializza una nuova istanza della classe Semaphore, specificando il numero iniziale di accessi e il numero massimo di accessi contemporanei, indicando 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 la sicurezza del controllo di accesso per il semaforo di sistema.Initializes a new instance of the Semaphore class, specifying the initial number of entries and the maximum number of concurrent entries, optionally specifying the name of a system semaphore object, specifying a variable that receives a value indicating whether a new system semaphore was created, and specifying security access control for the system semaphore.

Campi

WaitTimeout

Indica che si è verificato il timeout di un'operazione WaitAny(WaitHandle[], Int32, Boolean) prima della segnalazione di uno degli handle di attesa.Indicates that a WaitAny(WaitHandle[], Int32, Boolean) operation timed out before any of the wait handles were signaled. Questo campo è costante.This field is constant.

(Ereditato da WaitHandle)

Proprietà

Handle

Ottiene o imposta l'handle nativo del sistema operativo.Gets or sets the native operating system handle.

(Ereditato da WaitHandle)
SafeWaitHandle

Ottiene o imposta l'handle nativo del sistema operativo.Gets or sets the native operating system handle.

(Ereditato da WaitHandle)

Metodi

Close()

Rilascia tutte le risorse contenute nell'oggetto WaitHandle corrente.Releases all resources held by the current WaitHandle.

(Ereditato da WaitHandle)
CreateObjRef(Type)

Consente di creare un oggetto che contiene tutte le informazioni rilevanti necessarie per la generazione del proxy utilizzato per effettuare la comunicazione con un oggetto remoto.Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object.

(Ereditato da MarshalByRefObject)
Dispose()

Rilascia tutte le risorse usate dall'istanza corrente della classe WaitHandle.Releases all resources used by the current instance of the WaitHandle class.

(Ereditato da WaitHandle)
Dispose(Boolean)

Quando ne viene eseguito l'override in una classe derivata, libera le risorse non gestite usate da WaitHandle ed eventualmente di liberare le risorse gestite.When overridden in a derived class, releases the unmanaged resources used by the WaitHandle, and optionally releases the managed resources.

(Ereditato da WaitHandle)
Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.Determines whether the specified object is equal to the current object.

(Ereditato da Object)
GetAccessControl()

Ottiene la sicurezza del controllo di accesso per un semaforo di sistema denominato.Gets the access control security for a named system semaphore.

GetHashCode()

Funge da funzione hash predefinita.Serves as the default hash function.

(Ereditato da Object)
GetLifetimeService()

Consente di recuperare l'oggetto servizio di durata corrente per controllare i criteri di durata per l'istanza.Retrieves the current lifetime service object that controls the lifetime policy for this instance.

(Ereditato da MarshalByRefObject)
GetType()

Ottiene l'oggetto Type dell'istanza corrente.Gets the Type of the current instance.

(Ereditato da Object)
InitializeLifetimeService()

Ottiene un oggetto servizio di durata per controllare i criteri di durata per questa istanza.Obtains a lifetime service object to control the lifetime policy for this instance.

(Ereditato da MarshalByRefObject)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.Creates a shallow copy of the current Object.

(Ereditato da Object)
MemberwiseClone(Boolean)

Crea una copia dei riferimenti dell'oggetto MarshalByRefObject corrente.Creates a shallow copy of the current MarshalByRefObject object.

(Ereditato da MarshalByRefObject)
OpenExisting(String)

Apre il semaforo denominato specificato, se esistente.Opens the specified named semaphore, if it already exists.

OpenExisting(String, SemaphoreRights)

Apre il semaforo denominato specificato, se esistente, con l'accesso di sicurezza desiderato.Opens the specified named semaphore, if it already exists, with the desired security access.

Release()

Esce dal semaforo e restituisce il conteggio precedente.Exits the semaphore and returns the previous count.

Release(Int32)

Esce dal semaforo il numero di volte specificato e restituisce il conteggio precedente.Exits the semaphore a specified number of times and returns the previous count.

SetAccessControl(SemaphoreSecurity)

Imposta la sicurezza del controllo di accesso per un semaforo di sistema denominato.Sets the access control security for a named system semaphore.

ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.Returns a string that represents the current object.

(Ereditato da Object)
TryOpenExisting(String, Semaphore)

Apre il semaforo denominato specificato, se esistente, e restituisce un valore che indica se l'operazione è riuscita.Opens the specified named semaphore, if it already exists, and returns a value that indicates whether the operation succeeded.

TryOpenExisting(String, SemaphoreRights, Semaphore)

Apre il semaforo denominato specificato, se esistente, con l'accesso di sicurezza desiderato, e restituisce un valore che indica se l'operazione è riuscita.Opens the specified named semaphore, if it already exists, with the desired security access, and returns a value that indicates whether the operation succeeded.

WaitOne()

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale.Blocks the current thread until the current WaitHandle receives a signal.

(Ereditato da WaitHandle)
WaitOne(Int32)

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo.Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval in milliseconds.

(Ereditato da WaitHandle)
WaitOne(Int32, Boolean)

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.Blocks the current thread until the current WaitHandle receives a signal, using a 32-bit signed integer to specify the time interval and specifying whether to exit the synchronization domain before the wait.

(Ereditato da WaitHandle)
WaitOne(TimeSpan)

Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval.

(Ereditato da WaitHandle)
WaitOne(TimeSpan, Boolean)

Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un oggetto TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.Blocks the current thread until the current instance receives a signal, using a TimeSpan to specify the time interval and specifying whether to exit the synchronization domain before the wait.

(Ereditato da WaitHandle)

Implementazioni dell'interfaccia esplicita

IDisposable.Dispose()

Rilascia tutte le risorse usate da WaitHandle.Releases all resources used by the WaitHandle.

(Ereditato da WaitHandle)

Metodi di estensione

GetAccessControl(Semaphore)
SetAccessControl(Semaphore, SemaphoreSecurity)
GetSafeWaitHandle(WaitHandle)

Ottiene l'handle sicuro per un handle di attesa nativo del sistema operativo.Gets the safe handle for a native operating system wait handle.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Imposta un handle sicuro per un handle di attesa nativo del sistema operativo.Sets a safe handle for a native operating system wait handle.

Si applica a

Thread safety

Questo tipo è thread-safe.This type is thread safe.

Vedi anche