Semaphore und SemaphoreSlimSemaphore and SemaphoreSlim

Die System.Threading.Semaphore-Klasse stellt ein benanntes (systemweites) oder lokales Semaphor dar.The System.Threading.Semaphore class represents a named (systemwide) or local semaphore. Dabei handelt es sich um einen einfachen Wrapper um das Win32-Semaphorobjekt.It is a thin wrapper around the Win32 semaphore object. Win32-Semaphoren sind zählende Semaphoren, die zum Steuern des Zugriffs auf einen Ressourcenpool verwendet werden können.Win32 semaphores are counting semaphores, which can be used to control access to a pool of resources.

Die SemaphoreSlim-Klasse stellt ein einfaches, schnelles Semaphor dar, das zum Warten innerhalb eines einzelnen Prozesses verwendet werden kann, wenn die Wartezeiten voraussichtlich sehr kurz sind.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 basiert im möglichst hohen Maße auf Synchronisierungsprimitiven, die von Common Language Runtime (CLR) bereitgestellt werden.SemaphoreSlim relies as much as possible on synchronization primitives provided by the common language runtime (CLR). Es stellt jedoch auch verzögert initialisierte, Kernel-basierte Wait-Handles zur Unterstützung des Wartens auf mehrere Semaphoren bereit.However, it also provides lazily initialized, kernel-based wait handles as necessary to support waiting on multiple semaphores. SemaphoreSlim unterstützt auch die Verwendung von Abbruchtoken, unterstützt aber keine benannten Semaphoren oder die Verwendung eines Wait-Handles für die Synchronisierung.SemaphoreSlim also supports the use of cancellation tokens, but it does not support named semaphores or the use of a wait handle for synchronization.

Verwalten einer beschränkten RessourceManaging a Limited Resource

Threads wechseln in den Semaphor durch Aufrufen der WaitOne-Methode, die von der WaitHandle-Klasse geerbt wird, wenn es sich um ein System.Threading.Semaphore-Objekt handelt, bzw. von der SemaphoreSlim.Wait- oder SemaphoreSlim.WaitAsync-Methode, wenn es sich um ein SemaphoreSlim-Objekt handelt.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. Wenn der Aufruf zurückgegeben wird, wird der Zähler des Semaphors dekrementiert.When the call returns, the count on the semaphore is decremented. Wenn ein Thread den Zugang anfordert und die Anzahl null ist, wird der Thread blockiert.When a thread requests entry and the count is zero, the thread blocks. Da Threads das Semaphor durch Aufrufen von Freigeben der Semaphore.Release- oder SemaphoreSlim.Release-Methode freigeben, erhalten blockierte Threads Zugang.As threads release the semaphore by calling the Semaphore.Release or SemaphoreSlim.Release method, blocked threads are allowed to enter. Für die Aufnahme von blockierten Threads in das Semaphor gibt es keine festgelegte Reihenfolge, z. B. First in, First Out (FIFO) oder Last in, First Out (LIFO).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.

Ein Thread kann in das Semaphor mehrfach durch wiederholtes Aufrufen der System.Threading.Semaphore-Methode des WaitOne-Objekts oder der SemaphoreSlim-Methode des Wait-Objekts wechseln.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. Um das Semaphor freizugeben, kann der Thread entweder die Semaphore.Release()- oder SemaphoreSlim.Release()-Methodenüberladung aufrufen oder die Semaphore.Release(Int32)- oder SemaphoreSlim.Release(Int32)-Methodenüberladung aufrufen und die Anzahl der freizugebenden Einträge angeben.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.

Semaphoren und ThreadidentitätSemaphores and Thread Identity

Die zwei Semaphoren erzwingen keine Threadidentität für Aufrufe der Methoden WaitOne, Wait, Release und SemaphoreSlim.Release.The two semaphore types do not enforce thread identity on calls to the WaitOne, Wait, Release, and SemaphoreSlim.Release methods. Ein häufiges Verwendungsszenario für Semaphoren umfasst beispielsweise einen Producerthread und einem Consumerthread, wobei ein Thread den Zähler des Semaphors immer erhöht und der andere ihn immer verringert.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.

Der Programmierer ist dafür verantwortlich, sicherzustellen, dass ein Thread das Semaphor nicht zu oft freigibt.It is the programmer's responsibility to ensure that a thread does not release the semaphore too many times. Angenommen, ein Semaphor hat einen maximalen Zähler von zwei und Thread A sowie Thread B wechseln beide in das Semaphor.For example, suppose a semaphore has a maximum count of two, and that thread A and thread B both enter the semaphore. Wenn ein Programmierfehler in Thread B dazu führt, dass Release zweimal aufgerufen wird, sind beide Aufrufe erfolgreich.If a programming error in thread B causes it to call Release twice, both calls succeed. Der Zähler des Semaphors ist voll, und wenn Thread A schließlich Release aufruft, wird eine SemaphoreFullException ausgelöst.The count on the semaphore is full, and when thread A eventually calls Release, a SemaphoreFullException is thrown.

Benannte SemaphorenNamed Semaphores

Das Windows-Betriebssystem ermöglicht es, Semaphoren zu benennen.The Windows operating system allows semaphores to have names. Ein benanntes Semaphor ist systemweit sichtbar.A named semaphore is system wide. Das heißt, sobald das benannte Semaphor erstellt wurde, ist es für alle Threads in allen Prozessen sichtbar.That is, once the named semaphore is created, it is visible to all threads in all processes. Folglich kann ein benanntes Semaphore zum Synchronisieren der Aktivitäten von Prozessen und Threads verwendet werden.Thus, named semaphore can be used to synchronize the activities of processes as well as threads.

Sie können ein Semaphore-Objekt erstellen, das ein benanntes Systemsemaphor darstellt, indem Sie einen der Konstruktoren verwenden, die einen Namen angeben.You can create a Semaphore object that represents a named system semaphore by using one of the constructors that specifies a name.

Hinweis

Da benannte Semaphoren systemweit sichtbar sind, ist es möglich, mehrere Semaphore-Objekte zu haben, die dasselbe benannte Semaphor darstellen.Because named semaphores are system wide, it is possible to have multiple Semaphore objects that represent the same named semaphore. Bei jedem Aufruf eines Konstruktors oder der Semaphore.OpenExisting-Methode wird ein neues Semaphore-Objekt erstellt.Each time you call a constructor or the Semaphore.OpenExisting method, a new Semaphore object is created. Wenn Sie wiederholt denselben Namen angeben, werden mehrere Objekte erstellt, die desselbe benannte Semaphor darstellen.Specifying the same name repeatedly creates multiple objects that represent the same named semaphore.

Vorsicht ist geboten, wenn Sie benannte Semaphoren verwenden.Be careful when you use named semaphores. Da sie systemweit sichtbar sind, kann ein anderer Prozess, der den gleichen Namen verwendet, unerwartet in das Semaphor wechseln.Because they are system wide, another process that uses the same name can enter your semaphore unexpectedly. Böswilliger Code, der auf demselben Computer ausgeführt wird, könnte dies als Grundlage für einen Denial-of-Service-Angriff verwenden.Malicious code executing on the same computer could use this as the basis of a denial-of-service attack.

Verwenden Sie die Zugriffssteuerungssicherheit zum Schutz eines Semaphore-Objekts, das ein benanntes Semaphor darstellt, vorzugsweise unter Verwendung eines Konstruktors, der System.Security.AccessControl.SemaphoreSecurity-Objekt angibt.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. Sie können die Zugriffssteuerungssicherheit auch mithilfe der Semaphore.SetAccessControl-Methode anwenden, allerdings bleibt so ein Verwundbarkeitszeitfenster zwischen der Erstellung und dem Schutz des Semaphors.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. Der Schutz von Semaphoren mit Zugriffssteuerungssicherheit hilft beim Verhindern böswilliger Angriffe, das Problem unbeabsichtigter Namenskonflikte wird dadurch aber nicht gelöst.Protecting semaphores with access control security helps prevent malicious attacks, but does not solve the problem of unintentional name collisions.

Siehe auchSee also