Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die System.Threading.Semaphore Klasse stellt einen benannten (systemweiten) oder lokalen Semaphor dar. Es ist ein dünner Wrapper um das Win32-Semaphorobjekt. Win32-Semaphore sind zählende Semaphore, die verwendet werden können, um den Zugriff auf einen Ressourcenpool zu steuern.
Die SemaphoreSlim Klasse stellt ein einfaches, schnelles Semaphor dar, das verwendet werden kann, um innerhalb eines einzelnen Prozesses zu warten, wenn Wartezeiten voraussichtlich sehr kurz sind. SemaphoreSlim basiert so weit wie möglich auf Synchronisierungsgrundtypen, die von der Common Language Runtime (CLR) bereitgestellt werden. Es stellt jedoch auch verzögert initialisierte, Kernel-basierte Wait-Handles zur Unterstützung des Wartens auf mehrere Semaphoren bereit. SemaphoreSlim unterstützt auch die Verwendung von Abbruchtoken, unterstützt aber keine benannten Semaphoren oder die Verwendung eines Wait-Handles für die Synchronisierung.
Verwalten einer begrenzten Ressource
Threads treten in den Semaphor ein, indem sie die WaitOne Methode aufrufen, die von der WaitHandle Klasse geerbt wird, im Fall von einem System.Threading.Semaphore Objekt, oder die SemaphoreSlim.Wait oder SemaphoreSlim.WaitAsync Methode im Fall von einem SemaphoreSlim Objekt. Wenn der Aufruf zurückgegeben wird, wird der Zähler des Semaphors dekrementiert. Wenn ein Thread den Zugang anfordert und die Anzahl null ist, wird der Thread blockiert. Da Threads das Semaphor durch Aufrufen von Freigeben der Semaphore.Release- oder SemaphoreSlim.Release-Methode freigeben, erhalten blockierte Threads Zugang. 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).
Ein Thread kann das Semaphor mehrmals eingeben, indem die System.Threading.Semaphore Methode des WaitOne Objekts oder die SemaphoreSlim Methode des Wait Objekts wiederholt aufgerufen wird. 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.
Semaphoren und Threadidentität
Die beiden Semaphortypen erzwingen keine Threadidentität bei Aufrufen der Methoden WaitOne, Wait, Release und SemaphoreSlim.Release. 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.
Es liegt in der Verantwortung des Programmierers, sicherzustellen, dass ein Thread das Semaphor nicht zu oft freigibt. Angenommen, ein Semaphor hat eine maximale Anzahl von zwei, und Thread A und Thread B betreten beide das Semaphor. Wenn ein Programmierfehler in Thread B dazu führt, dass Release
zweimal aufgerufen wird, sind beide Aufrufe erfolgreich. Der Zähler des Semaphors ist voll, und wenn Thread A schließlich Release
aufruft, wird eine SemaphoreFullException ausgelöst.
Benannte Semaphoren
Das Windows-Betriebssystem ermöglicht Semaphoren, Namen zu haben. Ein benanntes Semaphor ist systemweit sichtbar. Das heißt, sobald der benannte Semaphor erstellt wurde, ist es für alle Threads in allen Prozessen sichtbar. So können benannte Semaphore verwendet werden, um die Aktivitäten von Prozessen sowie Threads zu synchronisieren.
Sie können ein Semaphore Objekt erstellen, das einen benannten Systemsemaphor darstellt, indem Sie einen der Konstruktoren verwenden, der einen Namen angibt.
Hinweis
Da benannte Semaphore systemweit sind, ist es möglich, mehrere Semaphore Objekte zu haben, die denselben benannten Semaphor darstellen. Jedes Mal, wenn Sie einen Konstruktor oder die Semaphore.OpenExisting Methode aufrufen, wird ein neues Semaphore Objekt erstellt. Wenn Sie denselben Namen angeben, werden wiederholt mehrere Objekte erstellt, die denselben benannten Semaphor darstellen.
Vorsicht ist geboten, wenn Sie benannte Semaphoren verwenden. Da sie systemweit sind, kann ein anderer Prozess, der denselben Namen verwendet, unerwartet auf das Semaphor zugreifen. Bösartiger Code, der auf demselben Computer ausgeführt wird, kann dies als Grundlage eines Denial-of-Service-Angriffs verwenden.
Verwenden Sie die Zugriffssteuerungssicherheit, um ein Semaphore Objekt zu schützen, das einen benannten Semaphor darstellt, vorzugsweise mithilfe eines Konstruktors, der ein System.Security.AccessControl.SemaphoreSecurity Objekt angibt. Sie können auch die Zugriffssteuerungssicherheit mithilfe der Semaphore.SetAccessControl Methode anwenden, aber dadurch bleibt ein Fenster der Sicherheitsanfälligkeit zwischen dem Zeitpunkt der Erstellung des Semaphors und der Zeit, zu der es geschützt ist. Der Schutz von Semaphoren mit Zugriffssteuerungssicherheit hilft beim Verhindern böswilliger Angriffe, das Problem unbeabsichtigter Namenskonflikte wird dadurch aber nicht gelöst.