Semaphore Classe

Définition

Limite le nombre de threads pouvant accéder simultanément à une ressource ou à un pool de ressources.

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
Héritage
Semaphore
Héritage
Attributs

Exemples

L’exemple de code suivant crée un sémaphore avec un nombre maximal de trois et un nombre initial de zéro. L’exemple démarre cinq threads, ce qui bloque l’attente du sémaphore. Le thread principal utilise la Release(Int32) surcharge de méthode pour augmenter le nombre de sémaphores au maximum, ce qui permet à trois threads d’entrer dans le sémaphore. Chaque thread utilise la méthode pour attendre une seconde, pour simuler le Thread.Sleep travail, puis appelle la Release() surcharge de méthode pour libérer le sémaphore. Chaque fois que le sémaphore est libéré, le nombre de sémaphores précédents s’affiche. Les messages de console suivent l’utilisation du sémaphore. L’intervalle de travail simulé est légèrement augmenté pour chaque thread, afin de faciliter la lecture de la sortie.

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

Remarques

Utilisez la classe pour contrôler l’accès Semaphore à un pool de ressources. Les threads entrent dans le sémaphore en appelant la WaitOne méthode, qui est héritée de la WaitHandle classe, et relâchez le sémaphore en appelant la Release méthode.

Le nombre sur un sémaphore est décrémenté chaque fois qu’un thread entre dans le sémaphore et incrémenté lorsqu’un thread libère le sémaphore. Lorsque le nombre est égal à zéro, les requêtes suivantes bloquent jusqu’à ce que d’autres threads libèrent le sémaphore. Lorsque tous les threads ont libéré le sémaphore, le nombre est à la valeur maximale spécifiée lors de la création du sémaphore.

Il n’existe aucun ordre garanti, tel que FIFO ou LIFO, dans lequel les threads bloqués entrent dans le sémaphore.

Un thread peut entrer le sémaphore plusieurs fois, en appelant la WaitOne méthode à plusieurs reprises. Pour libérer certaines ou toutes ces entrées, le thread peut appeler la surcharge de méthode sans Release() paramètre plusieurs fois, ou appeler la Release(Int32) surcharge de méthode qui spécifie le nombre d’entrées à libérer.

La Semaphore classe n’applique pas l’identité de thread sur les appels vers WaitOne ou Release. Il incombe au programmeur de s’assurer que les threads ne libèrent pas le sémaphore trop souvent. Par exemple, supposons qu’un sémaphore a un nombre maximal de deux, et que le thread A et le thread B entrent tous les deux dans le sémaphore. Si une erreur de programmation dans le thread B le conduit à appeler Release deux fois, les deux appels réussissent. Le nombre maximal du sémaphore sera alors atteint, et quand le thread A appellera Release, une exception SemaphoreFullException sera levée.

Les sémaphores sont de deux types : les sémaphores locaux et les sémaphores système nommés. Si vous créez un Semaphore objet à l’aide d’un constructeur qui accepte un nom, il est associé à un sémaphore de système d’exploitation de ce nom. Les sémaphores système nommés sont visibles dans tout le système d’exploitation et peuvent être utilisés pour synchroniser les activités des processus. Vous pouvez créer plusieurs Semaphore objets qui représentent le même sémaphore système nommé, et vous pouvez utiliser la OpenExisting méthode pour ouvrir un sémaphore système nommé existant.

Un sémaphore local n’existe que dans votre processus. Elle peut être utilisée par n’importe quel thread de votre processus qui a une référence à l’objet local Semaphore . Chaque Semaphore objet est un sémaphore local distinct.

Avertissement

Par défaut, un sémaphore nommé n’est pas limité à l’utilisateur qui l’a créé. D’autres utilisateurs peuvent être en mesure d’ouvrir et d’utiliser le sémaphore, y compris interférer avec le sémaphore en acquérant le sémaphore plusieurs fois et ne pas le libérer. Pour restreindre l’accès à des utilisateurs spécifiques, vous pouvez utiliser une surcharge de constructeur ou SemaphoreAcl passer un SemaphoreSecurity message lors de la création du sémaphore nommé. Évitez d’utiliser des sémaphores nommés sans restrictions d’accès sur les systèmes susceptibles d’avoir des utilisateurs non approuvés exécutant du code.

Constructeurs

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

Initialise une nouvelle instance de la Semaphore classe, en spécifiant le nombre initial d’entrées et le nombre maximal d’entrées simultanées, en spécifiant éventuellement le nom d’un objet sémaphore système, en spécifiant une variable qui reçoit une valeur indiquant si un nouveau sémaphore système a été créé et en spécifiant le contrôle d’accès de sécurité pour le sémaphore système.

Semaphore(Int32, Int32, String, Boolean)

Initialise une nouvelle instance de la Semaphore classe, en spécifiant le nombre initial d’entrées et le nombre maximal d’entrées simultanées, en spécifiant éventuellement le nom d’un objet sémaphore système et en spécifiant une variable qui reçoit une valeur indiquant si un sémaphore système a été créé.

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

Initialise une nouvelle instance de la Semaphore classe, en spécifiant le nombre initial d’entrées et le nombre maximal d’entrées simultanées, en spécifiant éventuellement le nom d’un objet et des options de sémaphore système pour définir l’étendue utilisateur et l’accès à l’étendue de session, et en spécifiant une variable qui reçoit une valeur indiquant si un nouveau sémaphore système a été créé.

Semaphore(Int32, Int32, String, NamedWaitHandleOptions)

Initialise une nouvelle instance de la Semaphore classe, en spécifiant le nombre initial d’entrées et le nombre maximal d’entrées simultanées, et éventuellement en spécifiant le nom d’un objet et des options de sémaphore système pour définir l’accès à l’étendue utilisateur et à l’étendue de session.

Semaphore(Int32, Int32, String)

Initialise une nouvelle instance de la Semaphore classe, en spécifiant le nombre initial d’entrées et le nombre maximal d’entrées simultanées et en spécifiant éventuellement le nom d’un objet sémaphore système.

Semaphore(Int32, Int32)

Initialise une nouvelle instance de la Semaphore classe, en spécifiant le nombre initial d’entrées et le nombre maximal d’entrées simultanées.

Champs

Nom Description
WaitTimeout

Indique qu’une WaitAny(WaitHandle[], Int32, Boolean) opération a expiré avant que les handles d’attente n’aient été signalés. Ce champ est constant.

(Hérité de WaitHandle)

Propriétés

Nom Description
Handle
Obsolète.
Obsolète.

Obtient ou définit le handle du système d’exploitation natif.

(Hérité de WaitHandle)
SafeWaitHandle

Obtient ou définit le handle du système d’exploitation natif.

(Hérité de WaitHandle)

Méthodes

Nom Description
Close()

Libère toutes les ressources détenues par le fichier actif WaitHandle.

(Hérité de WaitHandle)
CreateObjRef(Type)

Crée un objet qui contient toutes les informations pertinentes requises pour générer un proxy utilisé pour communiquer avec un objet distant.

(Hérité de MarshalByRefObject)
Dispose()

Libère toutes les ressources utilisées par l’instance actuelle de la WaitHandle classe.

(Hérité de WaitHandle)
Dispose(Boolean)

En cas de substitution dans une classe dérivée, libère les ressources non managées utilisées par le WaitHandle, et libère éventuellement les ressources managées.

(Hérité de WaitHandle)
Equals(Object)

Détermine si l’objet spécifié est égal à l’objet actuel.

(Hérité de Object)
GetAccessControl()

Obtient la sécurité du contrôle d’accès pour un sémaphore système nommé.

GetHashCode()

Sert de fonction de hachage par défaut.

(Hérité de Object)
GetLifetimeService()
Obsolète.

Récupère l’objet de service de durée de vie actuel qui contrôle la stratégie de durée de vie de cette instance.

(Hérité de MarshalByRefObject)
GetType()

Obtient la Type de l’instance actuelle.

(Hérité de Object)
InitializeLifetimeService()
Obsolète.

Obtient un objet de service de durée de vie pour contrôler la stratégie de durée de vie de cette instance.

(Hérité de MarshalByRefObject)
MemberwiseClone()

Crée une copie superficielle du Objectactuel.

(Hérité de Object)
MemberwiseClone(Boolean)

Crée une copie superficielle de l’objet actuel MarshalByRefObject .

(Hérité de MarshalByRefObject)
OpenExisting(String, NamedWaitHandleOptions)

Ouvre le sémaphore nommé spécifié, s’il existe déjà. Si les options sont définies sur l’utilisateur actuel uniquement, les contrôles d’accès de l’objet sont vérifiés pour l’utilisateur appelant.

OpenExisting(String, SemaphoreRights)

Ouvre le sémaphore nommé spécifié, s’il existe déjà, avec l’accès de sécurité souhaité.

OpenExisting(String)

Ouvre le sémaphore nommé spécifié, s’il existe déjà.

Release()

Quitte le sémaphore et retourne le nombre précédent.

Release(Int32)

Quitte le sémaphore un nombre spécifié de fois et retourne le nombre précédent.

SetAccessControl(SemaphoreSecurity)

Définit la sécurité du contrôle d’accès pour un sémaphore système nommé.

ToString()

Retourne une chaîne qui représente l’objet actuel.

(Hérité de Object)
TryOpenExisting(String, NamedWaitHandleOptions, Semaphore)

Ouvre le sémaphore nommé spécifié, s’il existe déjà, et retourne une valeur qui indique si l’opération a réussi. Si les options sont définies sur l’utilisateur actuel uniquement, les contrôles d’accès de l’objet sont vérifiés pour l’utilisateur appelant.

TryOpenExisting(String, Semaphore)

Ouvre le sémaphore nommé spécifié, s’il existe déjà, et retourne une valeur qui indique si l’opération a réussi.

TryOpenExisting(String, SemaphoreRights, Semaphore)

Ouvre le sémaphore nommé spécifié, s’il existe déjà, avec l’accès de sécurité souhaité et retourne une valeur qui indique si l’opération a réussi.

WaitOne()

Bloque le thread actuel jusqu’à ce que le courant WaitHandle reçoive un signal.

(Hérité de WaitHandle)
WaitOne(Int32, Boolean)

Bloque le thread actuel jusqu’à ce que le courant WaitHandle reçoive un signal, à l’aide d’un entier signé 32 bits pour spécifier l’intervalle de temps et spécifier s’il faut quitter le domaine de synchronisation avant l’attente.

(Hérité de WaitHandle)
WaitOne(Int32)

Bloque le thread actuel jusqu’à ce que le courant WaitHandle reçoive un signal, à l’aide d’un entier signé 32 bits pour spécifier l’intervalle de temps en millisecondes.

(Hérité de WaitHandle)
WaitOne(TimeSpan, Boolean)

Bloque le thread actuel jusqu’à ce que l’instance actuelle reçoive un signal, en utilisant un TimeSpan pour spécifier l’intervalle de temps et en spécifiant s’il faut quitter le domaine de synchronisation avant l’attente.

(Hérité de WaitHandle)
WaitOne(TimeSpan)

Bloque le thread actuel jusqu’à ce que l’instance actuelle reçoive un signal, en utilisant un TimeSpan pour spécifier l’intervalle de temps.

(Hérité de WaitHandle)

Implémentations d’interfaces explicites

Nom Description
IDisposable.Dispose()

Cette API prend en charge l'infrastructure du produit et n'est pas destinée à être utilisée directement à partir de votre code.

Libère toutes les ressources utilisées par le WaitHandle.

(Hérité de WaitHandle)

Méthodes d’extension

Nom Description
GetAccessControl(Semaphore)

Retourne les descripteurs de sécurité pour le .semaphore

GetSafeWaitHandle(WaitHandle)

Obtient le handle sécurisé pour un handle d’attente du système d’exploitation natif.

SetAccessControl(Semaphore, SemaphoreSecurity)

Définit les descripteurs de sécurité pour le sémaphore spécifié.

SetSafeWaitHandle(WaitHandle, SafeWaitHandle)

Définit un handle sécurisé pour un handle d’attente du système d’exploitation natif.

S’applique à

Cohérence de thread

Ce type est thread safe.

Voir aussi