Semafor och semaforSlim
Klassen representerar en namngiven System.Threading.Semaphore (systemomfattande) eller lokal semafor. Det är en tunn omslutning runt Win32-semaforobjektet. Win32-semaphores räknar semaphores, som kan användas för att styra åtkomsten till en pool med resurser.
Klassen SemaphoreSlim representerar en lätt, snabb semafor som kan användas för att vänta i en enda process när väntetiderna förväntas vara mycket korta. SemaphoreSlim förlitar sig så mycket som möjligt på synkronisering primitiver som tillhandahålls av common language runtime (CLR). Det ger dock också lättinitierade, kernelbaserade väntehandtag efter behov för att stödja väntan på flera semaforer. SemaphoreSlim stöder också användning av annulleringstoken, men det stöder inte namngivna semaphores eller användning av ett väntehandtag för synkronisering.
Hantera en begränsad resurs
Trådar anger semaforen genom att anropa WaitOne metoden, som ärvs från WaitHandle klassen, när det gäller ett System.Threading.Semaphore objekt, eller SemaphoreSlim.Wait - SemaphoreSlim.WaitAsync metoden, när det gäller ett SemaphoreSlim objekt. När anropet returnerar minskas antalet semaforer. När en tråd begär post och antalet är noll blockeras tråden. När trådar släpper semaforen genom att anropa Semaphore.Release metoden eller SemaphoreSlim.Release tillåts blockerade trådar att komma in. Det finns ingen garanterad ordning, till exempel först in, först ut (FIFO) eller sista in, först ut (LIFO), för blockerade trådar för att komma in i semaforen.
En tråd kan ange semafor flera gånger genom att anropa System.Threading.Semaphore objektets WaitOne metod eller SemaphoreSlim objektets Wait metod upprepade gånger. Om du vill frigöra semaforen kan tråden antingen anropa Semaphore.Release() metoden eller SemaphoreSlim.Release() överbelasta samma antal gånger, eller anropa överlagringen Semaphore.Release(Int32) av metoden eller SemaphoreSlim.Release(Int32) och ange antalet poster som ska släppas.
Semaforer och trådidentitet
De två semafortyperna tillämpar inte trådidentitet på anrop till WaitOnemetoderna , Wait, Releaseoch SemaphoreSlim.Release . Ett vanligt användningsscenario för semaforer omfattar till exempel en producenttråd och en konsumenttråd, där en tråd alltid ökar antalet semaforer och den andra alltid minskar den.
Det är programmerarens ansvar att se till att en tråd inte släpper ut semaforen för många gånger. Anta till exempel att en semafor har ett maximalt antal två, och att tråd A och tråd B båda anger semafor. Om ett programmeringsfel i tråd B gör att det anropas Release
två gånger lyckas båda anropen. Räkningen på semaforen är full, och när tråd A slutligen anropar Release
, kastas en SemaphoreFullException .
Med namnet Semaphores
Windows-operativsystemet tillåter att semaforer har namn. En namngiven semafor är system bred. När den namngivna semaforen har skapats är den alltså synlig för alla trådar i alla processer. Därför kan namngivna semafor användas för att synkronisera både processers och trådars aktiviteter.
Du kan skapa ett Semaphore objekt som representerar en namngiven systemsemafor med hjälp av någon av konstruktorerna som anger ett namn.
Kommentar
Eftersom namngivna semaphores är systemomfattande är det möjligt att ha flera Semaphore objekt som representerar samma namngivna semafor. Varje gång du anropar en konstruktor eller Semaphore.OpenExisting metod skapas ett nytt Semaphore objekt. Om du anger samma namn upprepade gånger skapas flera objekt som representerar samma namngivna semafor.
Var försiktig när du använder namngivna semaphores. Eftersom de är systemomfattande kan en annan process som använder samma namn ange din semafor oväntat. Skadlig kod som körs på samma dator kan använda detta som grund för en överbelastningsattack.
Använd åtkomstkontrollsäkerhet för att skydda ett Semaphore objekt som representerar en namngiven semafor, helst med hjälp av en konstruktor som anger ett System.Security.AccessControl.SemaphoreSecurity objekt. Du kan också använda åtkomstkontrollsäkerhet med hjälp av Semaphore.SetAccessControl metoden, men detta lämnar ett säkerhetsfönster mellan den tid då semaforen skapas och den tid det skyddas. Att skydda semaforer med åtkomstkontrollsäkerhet hjälper till att förhindra skadliga attacker, men löser inte problemet med oavsiktliga namnkollisioner.