Sdílet prostřednictvím


Semafor a SemaphoreSlim

Třída System.Threading.Semaphore představuje pojmenovaný (systémový) nebo místní semafor. Jedná se o tenkou obálku kolem semaforového objektu Win32. Win32 semafory jsou počítací semafory, které lze použít k řízení přístupu k množině zdrojů.

Třída SemaphoreSlim představuje jednoduchý, rychlý semaphore, který lze použít pro čekání v rámci jednoho procesu, když se očekává, že doby čekání budou velmi krátké. SemaphoreSlim spoléhá co nejvíce na primitivy synchronizace poskytované modulem CLR (Common Language Runtime). Poskytuje však také líně inicializované čekací mechanismy na bázi jádra, které podle potřeby podporují čekání na více semaforů. SemaphoreSlim podporuje také použití tokenů zrušení, ale nepodporuje pojmenované semafory nebo použití čekacího objektu pro synchronizaci.

Správa omezeného prostředku

Vlákna vstupují do semaforu voláním metody WaitOne, která je zděděná z třídy WaitHandle, v případě objektu System.Threading.Semaphore, anebo voláním metody SemaphoreSlim.Wait nebo SemaphoreSlim.WaitAsync v případě objektu SemaphoreSlim. Když se volání vrátí, hodnota semaforického čítače se sníží. Když vlákno požaduje položku a počet je nula, vlákno blokuje. Když vlákna uvolní semafor voláním metod Semaphore.Release nebo SemaphoreSlim.Release, blokovaná vlákna mohou vstoupit. Neexistuje žádné zaručené pořadí, jako je například první dovnitř, první ven (FIFO) nebo poslední dovnitř, první ven (LIFO), pro blokovaná vlákna vstupující do semaforu.

Vlákno může vícekrát vstoupit do semaforu voláním metody objektu System.Threading.Semaphore nebo metody objektu WaitOneSemaphoreSlim opakovaně. Chcete-li uvolnit semafor, vlákno může buď zavolat přetíženou metodu Semaphore.Release() nebo SemaphoreSlim.Release() stejný početkrát, nebo zavolat přetíženou metodu Semaphore.Release(Int32) nebo SemaphoreSlim.Release(Int32) a určit počet položek, které mají být uvolněny.

Semaphores a identita vlákna

Dva typy semaphore nevynucují identitu vlákna při volání WaitOne, Wait, Releasea SemaphoreSlim.Release metody. Například běžný scénář použití pro semafory zahrnuje vlákno producenta a vlákno příjemce, přičemž jedno vlákno vždy zvyšuje počet semaforů a druhé jej vždy snižuje.

Je zodpovědností programátora, aby se zajistilo, že vlákno nevyvolá semafor příliš mnohokrát. Předpokládejme například, že semafor má maximální počet dvou a že vlákno A a vlákno B vstoupí do semaforu. Pokud programovací chyba ve vlákně B způsobí, že se volá Release dvakrát, obě volání proběhnou úspěšně. Počet na semaforu je plný a když vlákno A nakonec zavolá Release, je vyvolána výjimka SemaphoreFullException.

Pojmenované semafory

Operační systém Windows umožňuje, aby semafory měly názvy. Pojmenovaný semaphore je široký systém. To znamená, že po vytvoření pojmenovaného semaforu je viditelný pro všechna vlákna ve všech procesech. Proto lze pojmenovaný semafor použít k synchronizaci aktivit jak procesů, tak vláken.

Můžete vytvořit objekt Semaphore, který představuje pojmenovaný systémový semafor, pomocí jednoho z konstruktorů, které určují název.

Poznámka:

Vzhledem k tomu, že pojmenované semafory jsou systémově rozšířené, může existovat více Semaphore objektů, které reprezentují ten samý pojmenovaný semafor. Při každém volání konstruktoru Semaphore.OpenExisting nebo metody se vytvoří nový Semaphore objekt. Zadání stejného názvu opakovaně vytvoří více objektů, které reprezentují stejný semafor.

Při použití pojmenovaných semaforů buďte opatrní. Protože jsou systémově, může jiný proces, který používá stejný název, neočekávaně vstoupit do semaforu. Škodlivý kód spuštěný na stejném počítači by ho mohl použít jako základ útoku na dostupnost služby.

Zabezpečení řízení přístupu použijte k ochraně objektu Semaphore , který představuje pojmenovaný semaphore, nejlépe pomocí konstruktoru, který určuje System.Security.AccessControl.SemaphoreSecurity objekt. Můžete také použít zabezpečení řízení přístupu pomocí metody Semaphore.SetAccessControl, tím však vzniká časové okno ohrožení mezi vytvořením semaforu a jeho ochranou. Ochrana semaforů pomocí zabezpečení řízení přístupu pomáhá zabránit škodlivým útokům, ale nevyřeší problém neúmyslných kolizí názvů.

Viz také