Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
.NET poskytuje řadu typů, které můžete použít k synchronizaci přístupu ke sdílenému prostředku nebo koordinaci interakce vlákna.
Důležité
K ochraně přístupu ke sdílenému prostředku použijte stejnou primitivní instanci synchronizace. Pokud k ochraně stejného prostředku použijete různé primitivní instance synchronizace, obcházíte ochranu poskytnutou primitivem synchronizace.
WaitHandle – třída a jednoduché typy synchronizace
Několik synchronizačních primitiv rozhraní .NET je odvozeno z třídy System.Threading.WaitHandle, která zapouzdřuje nativní systémový synchronizační popisovač a používá signalizační mechanismus pro interakci vláken. Mezi tyto třídy patří:
- System.Threading.Mutex, který uděluje výhradní přístup ke sdílenému prostředku. Stav mutexu je signalován, pokud ho žádné vlákno nevlastní.
- System.Threading.Semaphore, což omezuje počet vláken, která mohou současně přistupovat ke sdílenému prostředku nebo fondu prostředků. Stav semaforu je nastaven tak, aby signalizoval, když je jeho počet větší než nula a nepřiřazeno, pokud je jeho počet nula.
- System.Threading.EventWaitHandle, který představuje událost synchronizace vláken a může být buď v signálním nebo nesignálním stavu.
- System.Threading.AutoResetEvent, který vychází z EventWaitHandle a při signálu se po uvolnění jednoho čekajícího vlákna automaticky resetuje do nesignalizovaného stavu.
- System.Threading.ManualResetEvent, který je odvozen od EventWaitHandle a při signálu zůstává v signalizačním stavu, dokud není zavolána metoda Reset.
V rozhraní .NET Framework, protože WaitHandle odvozuje od System.MarshalByRefObject, lze tyto typy použít k synchronizaci aktivit vláken napříč hranicemi domény aplikace.
V rozhraní .NET Framework, .NET Core a .NET 5+ mohou některé z těchto typů představovat pojmenované systémové synchronizační rukojeti, které jsou viditelné v celém operačním systému a lze je využít pro synchronizaci mezi procesy:
- Mutex
- Semaphore (na Windows)
- EventWaitHandle (na Windows)
Další informace najdete v referenčních informacích k WaitHandle rozhraní API.
Lehké synchronizační typy nespoléhají na podkladové popisovače operačního systému a obvykle poskytují lepší výkon. Nelze je však použít pro synchronizaci mezi procesy. Tyto typy použijte pro synchronizaci vláken v jedné aplikaci.
Některé z těchto typů jsou alternativy k typům odvozených z WaitHandle. Jedná se například SemaphoreSlim o odlehčenou alternativu k Semaphore.
Synchronizace přístupu ke sdílenému prostředku
.NET poskytuje řadu synchronizačních primitiv pro řízení přístupu ke sdílenému prostředku několika vlákny.
Třída monitor
Třída System.Threading.Monitor uděluje vzájemně se vylučující přístup ke sdílenému prostředku získáním nebo uvolněním zámku objektu, který identifikuje prostředek. Zatímco se zámek drží, vlákno, které zámek obsahuje, může zámek znovu získat a uvolnit. Jakékoli jiné vlákno je blokováno od získání zámku a tato Monitor.Enter metoda čeká, až se zámek uvolní. Metoda Enter získá uvolněný zámek. Metodu Monitor.TryEnter můžete použít také k určení doby, po kterou se vlákno pokusí získat zámek. Protože třída má spřažení vláken, vlákno, které získalo zámek, musí uvolnit zámek voláním metody Monitor.
Můžete koordinovat interakci vláken, která získávají zámek na stejném objektu, pomocí metod Monitor.Wait, Monitor.Pulse a Monitor.PulseAll.
Další informace najdete v referenčních informacích k Monitor rozhraní API.
Poznámka:
Příkaz lock použijte v jazyce C# a příkaz SyncLock v jazyce Visual Basic k synchronizaci přístupu ke sdílenému prostředku místo přímého použití Monitor třídy. Tyto příkazy jsou implementovány pomocí metod Enter a Exit a za použití bloku try…finally k zajištění, že získaný zámek je vždy uvolněn.
třída Mutex
Třída System.Threading.Mutex , například Monitor, uděluje výhradní přístup ke sdílenému prostředku. Použijte jednu z přetížených metod Mutex.WaitOne pro vyžádání vlastnictví mutexu. Stejně jako Monitor, Mutex má spřažení vlákna a vlákno, které získalo mutex, musí ho uvolnit voláním metody Mutex.ReleaseMutex.
Na rozdíl od Monitortřídy Mutex lze použít pro synchronizaci mezi procesy. K tomu použijte pojmenovaný mutex, který je viditelný v celém operačním systému. Pokud chcete vytvořit pojmenovanou instanci mutex, použijte konstruktor Mutex , který určuje název. Můžete také volat metodu Mutex.OpenExisting pro otevření existujícího pojmenovaného systémového mutexu.
Další informace najdete v článku o mutexech a referenčních informacích k Mutex rozhraní API.
Struktura SpinLock
Struktura System.Threading.SpinLock , například Monitor, uděluje výhradní přístup ke sdílenému prostředku na základě dostupnosti zámku. Když SpinLock se pokusí získat zámek, který není k dispozici, čeká ve smyčce a opakovaně kontroluje, dokud zámek nebude dostupný.
Další informace o výhodách a nevýhodách použití spinlocku najdete v článku SpinLock a referenční k SpinLock rozhraní API.
Třída ReaderWriterLockSlim
Třída System.Threading.ReaderWriterLockSlim uděluje výhradní přístup ke sdílenému prostředku pro zápis a umožňuje více vláken přístup k prostředku současně pro čtení. Možná budete chtít použít ReaderWriterLockSlim k synchronizaci přístupu ke sdílené datové struktuře, která podporuje operace čtení bezpečné pro přístup z více vláken, ale vyžaduje výhradní přístup k provedení operace zápisu. Když vlákno požádá o výhradní přístup (například voláním metody ReaderWriterLockSlim.EnterWriteLock), následné požadavky čtenářů a zapisovačů se blokují, dokud všichni současní čtenáři nezavřou zámek a zapisovači nevstoupí a neukončí zámek.
Další informace najdete v referenčních informacích k ReaderWriterLockSlim rozhraní API.
Třídy Semaphore a SemaphoreSlim
Třídy System.Threading.Semaphore a System.Threading.SemaphoreSlim omezují počet vláken, která mohou současně přistupovat ke sdílenému prostředku nebo fondu prostředků. Další vlákna, která požadují prostředek, čekají, dokud žádné vlákno uvolní semaphore. Vzhledem k tomu, že semafor nemá spřažení vláken, může ho jedno vlákno získat a jiné ho může uvolnit.
SemaphoreSlim je zjednodušená alternativa Semaphore k synchronizaci pouze v rámci jedné hranice procesu.
Ve Windows můžete použít Semaphore pro synchronizaci mezi procesy. K tomu vytvořte Semaphore instanci, která představuje pojmenovaný systémový semafor, pomocí jednoho z konstruktorů Semaphore, které určují název, nebo pomocí Semaphore.OpenExisting metody. SemaphoreSlim nepodporuje pojmenované systémové semafory.
Další informace najdete v článku Semaphore a SemaphoreSlim a v referenčních informacích k rozhraní API Semaphore nebo SemaphoreSlim.
Interakce s vlákny nebo signalizace
Interakce vlákna (nebo signalizace vlákna) znamená, že vlákno musí čekat na oznámení nebo signál z jednoho nebo více vláken, aby bylo možné pokračovat. Pokud například vlákno A volá metodu Thread.Join vlákna B, vlákno A je blokováno, dokud vlákno B se dokončí. Primitivy synchronizace popsané v předchozí části poskytují jiný mechanismus pro signalizaci: uvolněním zámku vlákno oznámí jinému vláknu, že může pokračovat získáním zámku.
Tato část popisuje další konstruktory signalizace poskytované rozhraním .NET.
Třídy EventWaitHandle, AutoResetEvent, ManualResetEvent a ManualResetEventSlim
Třída System.Threading.EventWaitHandle představuje událost synchronizace vláken.
Událost synchronizace může být buď v nenastaveném nebo nastaveném stavu. Pokud je stav události nesignálovaný, vlákno, které volá přetížení události WaitOne, je blokováno, dokud není událost signalizována. Metoda EventWaitHandle.Set nastaví stav události na signálizovaný.
Chování EventWaitHandle, které bylo signalizováno, závisí na jeho režimu resetování.
- Objekt vytvořený s příznakem EventWaitHandle, EventResetMode.AutoReset, se automaticky resetuje po uvolnění jednoho čekajícího vlákna. Je to jako turniket, který umožňuje pokaždé projít pouze jednomu vláknu, když je to signalizováno. Třída System.Threading.AutoResetEvent , která je odvozena od EventWaitHandle, představuje toto chování.
- Vytvořený EventWaitHandle s příznakem EventResetMode.ManualReset zůstává aktivní, dokud není zavolána jeho metoda Reset. Je to jako brána, která je zavřená, dokud se neoznačí a pak zůstane otevřená, dokud ji někdo nezavře. Třída System.Threading.ManualResetEvent , která je odvozena od EventWaitHandle, představuje toto chování. Třída System.Threading.ManualResetEventSlim je odlehčená alternativa k ManualResetEvent.
Ve Windows můžete použít EventWaitHandle pro synchronizaci mezi procesy. K tomu vytvořte EventWaitHandle instanci, která představuje pojmenovanou událost synchronizace systému pomocí jednoho z konstruktorů EventWaitHandle , které určují název nebo metodu EventWaitHandle.OpenExisting .
Další informace naleznete v článku EventWaitHandle . Referenční informace k rozhraní API naleznete v tématu EventWaitHandle, AutoResetEvent, ManualResetEventa ManualResetEventSlim.
Třída CountdownEvent
Třída System.Threading.CountdownEvent představuje událost, která se nastaví, když jeho počet je nula. I když CountdownEvent.CurrentCount je větší než nula, vlákno, které volá CountdownEvent.Wait , je blokováno. Volání CountdownEvent.Signal pro snížení počtu událostí
Na rozdíl od ManualResetEvent nebo ManualResetEventSlim, které můžete použít k odblokování více vláken s signálem z jednoho vlákna, můžete použít CountdownEvent k odblokování jednoho nebo více vláken se signály z více vláken.
Další informace najdete v článku CountdownEvent a v referenci rozhraní CountdownEvent API.
Třída bariér
Třída System.Threading.Barrier představuje bariéru spuštění vlákna. Vlákno, které volá metodu Barrier.SignalAndWait, signalizuje, že dosáhlo bariéry a čeká, až ostatní vlákna účastníků dorazí k bariéře. Když se všechna vlákna účastníků dostanou do bariéry, budou pokračovat a bariéra se resetuje a lze ji znovu použít.
Před pokračováním do další fáze výpočtu můžete použít Barrier , když jedno nebo více vláken vyžaduje výsledky jiných vláken.
Další informace najdete v článku o bariérách a v referenčních informacích k Barrier rozhraní API.
Interlocked – třída
Třída System.Threading.Interlocked poskytuje statické metody, které provádějí jednoduché atomické operace s proměnnou. Mezi tyto atomické operace patří sčítání, zvýšení a dekrementace, výměna a podmíněná výměna, které závisí na porovnání, a operace čtení 64bitové celočíselné hodnoty.
Další informace najdete v referenčních informacích k Interlocked rozhraní API.
SpinWait – struktura
Struktura System.Threading.SpinWait poskytuje podporu pro čekání založené na spinech. Můžete ji použít, když vlákno musí čekat na to, aby byla událost signalizována nebo podmínka splněna, ale očekává se, že skutečná doba čekání bude kratší než doba čekání, která by byla požadována při použití čekacího úchytu nebo jiném zablokování vlákna. Pomocí SpinWait, můžete zadat krátkou dobu, která se má otáčet při čekání, a pak výnos (například čekáním nebo spaním) pouze v případě, že podmínka nebyla splněna v zadaném čase.
Další informace najdete v článku o SpinWait a referenčních informacích k SpinWait rozhraní API.