A szinkronizálási primitívek áttekintése

A .NET számos típust biztosít, amelyekkel szinkronizálhatja a megosztott erőforráshoz való hozzáférést, vagy koordinálhatja a szál interakcióját.

Fontos

Használja ugyanazt a szinkronizálási primitív példányt a megosztott erőforrások hozzáférésének védelméhez. Ha ugyanazt az erőforrást különböző szinkronizálási primitív példányokkal védi, megkerüli a szinkronizálási primitív által biztosított védelmet.

WaitHandle osztály és egyszerűsített szinkronizálási típusok

Több .NET-szinkronizálási primitív származik az System.Threading.WaitHandle osztályból, amely egy natív operációsrendszer-szinkronizálási leírót foglal magában, és egy jelátviteli mechanizmust használ a szálak közötti interakcióhoz. Ezek az osztályok a következők:

  • System.Threading.Mutex, amely kizárólagos hozzáférést biztosít egy megosztott erőforráshoz. A mutex állapota akkor lesz jelezve, ha egyik szál sem rendelkezik vele.
  • System.Threading.Semaphore, amely korlátozza a megosztott erőforrásokhoz vagy erőforráskészletekhez egyidejűleg hozzáférő szálak számát. A szemaphore állapota akkor lesz jelezve, ha a száma nagyobb, mint nulla, és nem lesz aláírva, ha a száma nulla.
  • System.Threading.EventWaitHandle, amely egy szálszinkronizálási eseményt jelöl, és jelezve vagy aláíratlan állapotban lehet.
  • System.Threading.AutoResetEvent, amely egyetlen várakozási szál felszabadítása után automatikusan visszaáll egy aláíratlan állapotra, amely a EventWaitHandle jelzés alapján, illetve jelzés esetén automatikusan visszaáll egy aláíratlan állapotra.
  • System.Threading.ManualResetEvent, amely a metódus meghívásáig Reset a rendszerből EventWaitHandle származik, és a jelzéskor a jelzett állapotban marad.

A .NET-keretrendszer, mivel WaitHandle származikSystem.MarshalByRefObject, ezek a típusok használhatók a szálak tevékenységeinek szinkronizálására az alkalmazás tartományhatárai között.

A .NET-keretrendszer, a .NET Core és a .NET 5+ rendszerekben ezek közül néhány névvel ellátott rendszerszinkronizálási fogópontot jelölhet, amelyek az operációs rendszer egészében láthatók, és a folyamatközi szinkronizáláshoz használhatók:

További információ: API-referencia WaitHandle .

Az egyszerűsített szinkronizálási típusok nem támaszkodnak az alapul szolgáló operációsrendszer-leírókra, és általában jobb teljesítményt nyújtanak. A folyamatközi szinkronizáláshoz azonban nem használhatók. Használja ezeket a típusokat a szálszinkronizáláshoz egy alkalmazásban.

Néhány ilyen típus alternatíva a származtatott típusok helyett WaitHandle. Például SemaphoreSlim egy egyszerű alternatíva a Semaphore.

Megosztott erőforráshoz való hozzáférés szinkronizálása

A .NET számos szinkronizálási primitívet biztosít a megosztott erőforráshoz való hozzáférés szabályozásához több szálon.

Osztály figyelése

Az System.Threading.Monitor osztály az erőforrást azonosító objektum zárolásának beszerzésével vagy felszabadításával kölcsönösen kizárólagos hozzáférést biztosít egy megosztott erőforráshoz. A zárolás megtartása közben a zárolást tartalmazó szál ismét beszerezheti és feloldhatja a zárolást. Minden más szál le van tiltva a zárolás beszerzésében, és a Monitor.Enter metódus megvárja a zárolás feloldását. A Enter metódus feloldott zárolást szerez be. A metódussal Monitor.TryEnter megadhatja azt az időtartamot is, amely alatt egy szál megpróbál zárolást szerezni. Mivel az Monitor osztály szál affinitással rendelkezik, a zárolást beszerző szálnak fel kell szabadítania a zárolást a Monitor.Exit metódus meghívásával.

Koordinálhatja azoknak a szálaknak az interakcióját, amelyek zárolva lesznek ugyanazon az objektumon a Monitor.Wait, Monitor.Pulseés Monitor.PulseAll metódusok használatával.

További információ: API-referencia Monitor .

Feljegyzés

A C# zárolási utasításával és a Visual Basic SyncLock utasításával szinkronizálhatja a megosztott erőforráshoz való hozzáférést az Monitor osztály közvetlen használata helyett. Ezek az utasítások a Enter metódusok és Exit a try…finally blokkok használatával valósulnak meg, hogy a beszerzett zárolás mindig felszabaduljon.

Mutex-osztály

Az System.Threading.Mutex osztály például Monitorkizárólagos hozzáférést biztosít egy megosztott erőforráshoz. A Mutex.WaitOne metódus túlterheléseinek egyikével kérheti a mutex tulajdonjogát. Például Monitora Mutex szál affinitása van, és a mutexet beszerző szálnak fel kell szabadítania a Mutex.ReleaseMutex metódus meghívásával.

Ellentétben Monitoraz Mutex osztály a folyamatok közötti szinkronizáláshoz használható. Ehhez használjon egy elnevezett mutexet, amely az operációs rendszeren keresztül látható. Névvel ellátott mutex-példány létrehozásához használjon egy nevet meghatározó Mutex-konstruktort . Meghívhatja a Mutex.OpenExisting metódust egy meglévő, névvel ellátott rendszer-mutex megnyitásához is.

További információkért tekintse meg a Mutexes-cikket és az API-referenciát Mutex .

SpinLock-struktúra

A System.Threading.SpinLock struktúra például Monitorkizárólagos hozzáférést biztosít egy megosztott erőforráshoz a zárolás rendelkezésre állása alapján. Ha SpinLock egy nem elérhető zárolást próbál beszerezni, az egy ciklusban várakozik, és ismételten ellenőrzi, hogy a zárolás elérhetővé válik-e.

A spin lock használatának előnyeiről és hátrányairól a SpinLock-cikkben és az SpinLock API-referenciaban talál további információt.

ReaderWriterLockSlim osztály

Az System.Threading.ReaderWriterLockSlim osztály kizárólagos hozzáférést biztosít egy megosztott erőforráshoz íráshoz, és lehetővé teszi, hogy egyszerre több szál is hozzáférhessen az erőforráshoz olvasás céljából. Érdemes lehet szinkronizálni ReaderWriterLockSlim a hozzáférést egy megosztott adatstruktúrához, amely támogatja a szálbiztos olvasási műveleteket, de kizárólagos hozzáférést igényel az írási művelet végrehajtásához. Ha egy szál kizárólagos hozzáférést kér (például a metódus meghívásával), a ReaderWriterLockSlim.EnterWriteLock későbbi olvasói és írói kérések blokkolva lesznek, amíg az összes meglévő olvasó ki nem lép a zárolásból, és az író belépett és kilépett a zárolásból.

További információ: API-referencia ReaderWriterLockSlim .

Semaphore és SemaphoreSlim osztályok

Az System.Threading.Semaphore és System.Threading.SemaphoreSlim az osztályok korlátozzák a megosztott erőforrásokhoz vagy erőforráskészletekhez egyidejűleg hozzáférő szálak számát. Az erőforrást kérő további szálak megvárják, amíg bármely szál felengedi a szemaphore-t. Mivel a szemaphore nem rendelkezik szál affinitással, egy szál képes megszerezni a szemafort, egy másik pedig felszabadíthatja azt.

SemaphoreSlim egyszerű alternatívát jelent, Semaphore és csak egyetlen folyamathatáron belüli szinkronizáláshoz használható.

Windows rendszeren használhatja Semaphore a folyamatközi szinkronizálást. Ehhez hozzon létre egy példánytSemaphore, amely egy elnevezett rendszerszemafort jelöl egy név vagy Semaphore.OpenExisting metódust meghatározó Semaphore-konstruktorok egyikével. SemaphoreSlim nem támogatja a nevesített rendszerszemforokat.

További információkért tekintse meg a Semaphore és SemaphoreSlim cikket, valamint az Semaphore VAGY SemaphoreSlim API-referenciát.

Szál interakciója vagy jelzése

A szál interakciója (vagy menetjelzése) azt jelenti, hogy a szálnak várnia kell egy vagy több szál értesítésére vagy jelére a folytatáshoz. Ha például az A szál meghívja a Thread.Join B szál metódusát, az A szál le lesz tiltva, amíg a B szál be nem fejeződik. Az előző szakaszban leírt szinkronizálási primitívek eltérő jelzési mechanizmust biztosítanak: a zárolás felszabadításával a szál értesíti a másik szálat, hogy a zárolás megszerzésével folytathatja.

Ez a szakasz a .NET által biztosított további jelátviteli szerkezeteket ismerteti.

EventWaitHandle, AutoResetEvent, ManualResetEvent és ManualResetEventSlim osztályok

Az System.Threading.EventWaitHandle osztály egy szálszinkronizálási eseményt jelöl.

A szinkronizálási esemény lehet aláíratlan vagy jelzés nélküli állapotban is. Ha egy esemény állapota nincs aláírva, az esemény túlterhelését WaitOne hívó szál le lesz tiltva, amíg egy eseményt nem jelez. A EventWaitHandle.Set metódus egy esemény állapotát jelzi.

A jelzést kapott viselkedés EventWaitHandle az alaphelyzetbe állítási módtól függ:

Windows rendszeren használhatja EventWaitHandle a folyamatközi szinkronizálást. Ehhez hozzon létre egy példánytEventWaitHandle, amely egy elnevezett rendszerszinkronizálási eseményt jelöl a nevet vagy a EventWaitHandle.OpenExisting metódust meghatározó EventWaitHandle-konstruktorok egyikével.

További információ: EventWaitHandle cikk. Az API-referencia: EventWaitHandle, AutoResetEvent, ManualResetEventés ManualResetEventSlim.

CountdownEvent osztály

Az System.Threading.CountdownEvent osztály egy olyan eseményt jelöl, amely akkor lesz beállítva, ha a száma nulla. Míg CountdownEvent.CurrentCount a rendszer nullánál nagyobb, a hívásokat kezdeményező CountdownEvent.Wait szál le van tiltva. Hívás CountdownEvent.Signal egy esemény számának megcselekedésére.

Ezzel ellentétben ManualResetEventManualResetEventSlimvagy – amellyel több szálat is letilthat egy szál jelével –, egy vagy több szál letiltását feloldhatja CountdownEvent több szál jeleivel.

További információkért tekintse meg a CountdownEvent cikket és az API-referenciát CountdownEvent .

Akadályosztály

Az System.Threading.Barrier osztály egy szálvégrehajtási korlátot jelöl. Egy szál, amely meghívja a Barrier.SignalAndWait metódust, azt jelzi, hogy elérte az akadályt, és megvárja, amíg más résztvevők szálai elérik az akadályt. Amikor az összes résztvevő szál eléri az akadályt, továbblépnek, és a sorompó alaphelyzetbe áll, és újra felhasználhatók.

Akkor használhatja Barrier , ha egy vagy több szál más szálak eredményeit igényli, mielőtt továbblépne a következő számítási fázisra.

További információkért tekintse meg a Barrier cikket és az API-referenciát Barrier .

Összekapcsolt osztály

Az System.Threading.Interlocked osztály olyan statikus metódusokat biztosít, amelyek egyszerű atomi műveleteket hajtanak végre egy változón. Ezek az atomi műveletek közé tartozik az összeadás, a növekmény és a decrement, az összehasonlítástól függő csere és feltételes csere, valamint egy 64 bites egész számérték olvasási művelete.

További információ: API-referencia Interlocked .

SpinWait struktúra

A System.Threading.SpinWait struktúra támogatja a spin-alapú várakozást. Érdemes lehet használni, ha egy szálnak várnia kell egy esemény jelzésére vagy egy feltétel teljesítésére, de ha a tényleges várakozási idő várhatóan kisebb lesz, mint a várakozási fogópont használatával vagy a szál egyéb módon történő blokkolásával szükséges várakozási idő. A használatával SpinWaitmegadhat egy rövid időtartamot a várakozás közbeni pörgetéshez, majd csak akkor ad vissza (például várakozással vagy alvással), ha a feltétel nem teljesült a megadott időpontban.

További információkért lásd a SpinWait cikket és az API-referenciát SpinWait .

Lásd még