Semaphore et SemaphoreSlimSemaphore and SemaphoreSlim

La classe System.Threading.Semaphore représente un sémaphore local ou nommé (visible à l'échelle du système).The System.Threading.Semaphore class represents a named (systemwide) or local semaphore. Il s'agit d'un wrapper mince entourant l'objet sémaphore Win32.It is a thin wrapper around the Win32 semaphore object. Les sémaphores Win32 sont des sémaphores de comptage qui peuvent être utilisés pour contrôler l'accès à un pool de ressources.Win32 semaphores are counting semaphores, which can be used to control access to a pool of resources.

La classe SemaphoreSlim représente un sémaphore léger et rapide qui peut être utilisé pour l'attente dans un processus unique quand les temps d'attente sont censés être très courts.The SemaphoreSlim class represents a lightweight, fast semaphore that can be used for waiting within a single process when wait times are expected to be very short. SemaphoreSlim repose autant que possible sur les primitives de synchronisation fournies par le Common Language Runtime (CLR).SemaphoreSlim relies as much as possible on synchronization primitives provided by the common language runtime (CLR). Toutefois, il fournit également des handles d'attente initialisés tardivement et basés sur le noyau qui permettent l'attente de plusieurs sémaphores.However, it also provides lazily initialized, kernel-based wait handles as necessary to support waiting on multiple semaphores. SemaphoreSlim prend également en charge l'utilisation de jetons d'annulation, mais il ne prend pas en charge les sémaphores nommés ni l'utilisation d'un handle d'attente pour la synchronisation.SemaphoreSlim also supports the use of cancellation tokens, but it does not support named semaphores or the use of a wait handle for synchronization.

Gestion d'une ressource limitéeManaging a Limited Resource

Les threads entrent dans le sémaphore en appelant la méthode WaitOne, qui est héritée de la classe WaitHandle, dans le cas d'un objet System.Threading.Semaphore, ou la méthode SemaphoreSlim.Wait ou SemaphoreSlim.WaitAsync dans le cas d'un objet SemaphoreSlim.Threads enter the semaphore by calling the WaitOne method, which is inherited from the WaitHandle class, in the case of a System.Threading.Semaphore object, or the SemaphoreSlim.Wait or SemaphoreSlim.WaitAsync method, in the case of a SemaphoreSlim object. Quand l'appel est retourné, le nombre du sémaphore est décrémenté.When the call returns, the count on the semaphore is decremented. Quand un thread demande à entrer et que le nombre est égal à zéro, le thread se bloque.When a thread requests entry and the count is zero, the thread blocks. Quand les threads libèrent le sémaphore en appelant la méthode Semaphore.Release ou SemaphoreSlim.Release, les threads bloqués sont autorisés à entrer.As threads release the semaphore by calling the Semaphore.Release or SemaphoreSlim.Release method, blocked threads are allowed to enter. Il n'existe aucun ordre garanti (tel que premier entré, premier sorti (FIFO) ou dernier entré, premier sorti (LIFO)), pour les threads bloqués devant entrer dans le sémaphore.There is no guaranteed order, such as first-in, first-out (FIFO) or last-in, first-out (LIFO), for blocked threads to enter the semaphore.

Un thread peut entrer dans le sémaphore plusieurs fois en appelant la méthode System.Threading.Semaphore de l'objet WaitOne ou la méthode SemaphoreSlim de l'objet Wait à plusieurs reprises.A thread can enter the semaphore multiple times by calling the System.Threading.Semaphore object's WaitOne method or the SemaphoreSlim object's Wait method repeatedly. Pour libérer le sémaphore, le thread peut appeler la surcharge de méthode Semaphore.Release() ou SemaphoreSlim.Release() le même nombre de fois, ou appeler la surcharge de méthode Semaphore.Release(Int32) ou SemaphoreSlim.Release(Int32) et spécifier le nombre d’entrées à libérer.To release the semaphore, the thread can either call the Semaphore.Release() or SemaphoreSlim.Release() method overload the same number of times, or call the Semaphore.Release(Int32) or SemaphoreSlim.Release(Int32) method overload and specify the number of entries to be released.

Sémaphores et identité de threadSemaphores and Thread Identity

Les deux types de sémaphores n'appliquent pas l'identité de thread sur les appels aux méthodes WaitOne, Wait, Release et SemaphoreSlim.Release.The two semaphore types do not enforce thread identity on calls to the WaitOne, Wait, Release, and SemaphoreSlim.Release methods. Par exemple, un scénario classique d'utilisation des sémaphores implique un thread producteur et un thread consommateur, avec un thread incrémentant le nombre du sémaphore et l'autre le décrémentant.For example, a common usage scenario for semaphores involves a producer thread and a consumer thread, with one thread always incrementing the semaphore count and the other always decrementing it.

Il est de la responsabilité du programmeur de garantir qu’un thread ne libère pas le sémaphore trop souvent.It is the programmer's responsibility to ensure that a thread does not release the semaphore too many times. Supposons, par exemple, qu'un sémaphore ait un nombre maximal égal à deux et que le thread A et le thread B entrent dans le sémaphore.For example, suppose a semaphore has a maximum count of two, and that thread A and thread B both enter the semaphore. Si une erreur de programmation dans le thread B le conduit à appeler Release deux fois, les deux appels aboutiront.If a programming error in thread B causes it to call Release twice, both calls succeed. Le nombre maximal du sémaphore sera alors atteint, et quand le thread A appellera Release, une exception SemaphoreFullException sera levée.The count on the semaphore is full, and when thread A eventually calls Release, a SemaphoreFullException is thrown.

Sémaphores nommésNamed Semaphores

Le système d'exploitation Windows permet d'attribuer un nom aux sémaphores.The Windows operating system allows semaphores to have names. Un sémaphore nommé est disponible à l'échelle du système.A named semaphore is system wide. C'est-à-dire qu'une fois créé, le sémaphore nommé est visible par tous les threads de tous les processus.That is, once the named semaphore is created, it is visible to all threads in all processes. Par conséquent, un sémaphore nommé peut être utilisé pour synchroniser aussi bien des activités de processus que des threads.Thus, named semaphore can be used to synchronize the activities of processes as well as threads.

Vous pouvez créer un objet Semaphore qui représente un sémaphore système nommé en utilisant l'un des constructeurs qui spécifient un nom.You can create a Semaphore object that represents a named system semaphore by using one of the constructors that specifies a name.

Notes

Étant donné que les sémaphores nommés sont disponibles à l'échelle du système, il est possible que plusieurs objets Semaphore représentent le même sémaphore nommé.Because named semaphores are system wide, it is possible to have multiple Semaphore objects that represent the same named semaphore. Chaque fois que vous appelez un constructeur ou la méthode Semaphore.OpenExisting, un nouvel objet Semaphore est créé.Each time you call a constructor or the Semaphore.OpenExisting method, a new Semaphore object is created. Le fait de spécifier un même nom plusieurs fois crée plusieurs objets qui représentent le même sémaphore nommé.Specifying the same name repeatedly creates multiple objects that represent the same named semaphore.

Soyez prudent lorsque vous utilisez des sémaphores nommés.Be careful when you use named semaphores. Étant donné qu'ils sont disponibles à l'échelle du système, un autre processus portant le même nom peut entrer dans votre sémaphore sans que vous vous y attendiez.Because they are system wide, another process that uses the same name can enter your semaphore unexpectedly. Du code malveillant exécuté sur le même ordinateur pourrait s'en servir pour une attaque par déni de service.Malicious code executing on the same computer could use this as the basis of a denial-of-service attack.

Utilisez la sécurité de contrôle d'accès pour protéger un objet Semaphore qui représente un sémaphore nommé, de préférence en utilisant un constructeur qui spécifie un objet System.Security.AccessControl.SemaphoreSecurity.Use access control security to protect a Semaphore object that represents a named semaphore, preferably by using a constructor that specifies a System.Security.AccessControl.SemaphoreSecurity object. Vous pouvez également appliquer la sécurité de contrôle d'accès à l'aide de la méthode Semaphore.SetAccessControl. Sachez toutefois que cela crée une vulnérabilité entre le moment où le sémaphore est créé et celui où il est protégé.You can also apply access control security using the Semaphore.SetAccessControl method, but this leaves a window of vulnerability between the time the semaphore is created and the time it is protected. La protection des sémaphores grâce à la sécurité de contrôle d'accès empêche les attaques malveillantes, mais ne résout pas le problème des conflits de noms involontaires.Protecting semaphores with access control security helps prevent malicious attacks, but does not solve the problem of unintentional name collisions.

Voir aussiSee also