Programovanie

Moje dva centy na SpinLock v .Net

Predstavte si situáciu, v ktorej sa vlákno snaží získať prístup k zdieľanému prostriedku, ale prostriedok je už uzamknutý, takže vlákno musí čakať, kým sa zámok neuvoľní. Tu prichádza na rad synchronizácia vlákien. Synchronizácia vlákien sa používa na zabránenie viacerým vláknam v súčasnom prístupe k zdieľanému prostriedku. Microsoft .Net Framework poskytuje podporu pre celý rad synchronizačných primitívov, ktoré možno použiť na riadenie správania vlákien a predchádzanie rasovým podmienkam. Mutex a Spinlock sú dva populárne synchronizačné mechanizmy používané na synchronizáciu prístupu k zdieľanému prostriedku.

SpinLock je alternatívou k blokovaniu synchronizácie. SpinLock (tiež známy ako „Busy Waiting“) je mechanizmus, pomocou ktorého je možné vytvoriť vlákno, ktoré sa snaží získať zámok, počkať v slučke, kým nebude mať prístup k prostriedku. Upozorňujeme, že SpinLock môže v porovnaní s Mutexom fungovať rýchlejšie, pretože prepínanie kontextu je obmedzené. Mali by ste však používať program SpinLocks, iba ak má kritická sekcia vykonávať minimálne množstvo práce, t. J. Program SpinLock je držaný veľmi krátko. SpinLocks sa zvyčajne uprednostňujú v symetrických viacprocesorových systémoch na neustále zisťovanie dostupnosti zdroja namiesto kontextových prepínačov.

Čo je SpinLock a prečo je potrebný?

SpinLock vykonáva rušné čakanie a môže ponúknuť lepší výkon pri použití vo viacjadrových systémoch, najmä keď je lacné čakať v slučke a združovať zdroj, namiesto toho, aby ho blokoval. To je obzvlášť užitočné, keď sú doby podržania zámku krátke. Inými slovami, môžete využiť výhodu SpinLock vo viacjadrových systémoch na zníženie režijných nákladov spojených s prepínaním kontextu, ak je čas strávený vo vnútri kritickej sekcie malý. Kritická sekcia môže byť definovaná ako dátová štruktúra alebo zdroj, ktorý je zdieľaný viacerými vláknami, ale jedno a iba jedno vlákno k nej môže mať prístup v danom okamihu.

Je potrebné poznamenať, že dlhodobé držanie SpinLocku by bolo jednoducho plytvaním prostriedkami systému a škodlivými pre výkon aplikácie. V podstate, ak očakávate, že blokovanie bude mať značné trvanie, SpinLock by sa nikdy nemal používať - ​​SpinLock používajte iba v prípade, že sú doby blokovania primerane krátkeho trvania.

SpinLock sa zvyčajne používajú pri práci s prerušeniami na vykonávanie rušného čakania vo vnútri slučky, kým sa zdroj nesprístupní. SpinLock nespôsobuje preempovanie vlákna, skôr sa točí, kým sa neuvoľní zámok na prostriedku.

Programovanie SpinLock v .Net

Upozorňujeme, že SpinLock je definovaný ako štruktúra v .Net, t. J. Je z dôvodov výkonu definovaná ako typ hodnoty. Ak teda prechádzate okolo inštancie SpinLock, mali by ste ju odovzdať odkazom, a nie hodnotou. V tejto časti preskúmame, ako môžeme programovať SpinLock v .Net. Ak chcete implementovať SpinLock v .Net, budete musieť využiť výhodu triedy SpinLock, ktorá je k dispozícii v mennom priestore System.Threading.

Nasledujúci zoznam kódov ukazuje, ako môžete používať SpinLock v .Net.

SpinLock spinLock = nový SpinLock (true);

bool isLocked = false;

skús

{

spinLock.Enter (ref isLocked);

// Sem napíš obvyklý kód

}

konečne

{

if (isLocked)

spinLock.Exit ();

}

SpinWait

Upozorňujeme, že rovnako ako SpinLock, aj SpinWait je štruktúra a nie trieda. Podobne ako v prípade SpinLock, aj tu môžete použiť program SpinWait na napísanie synchronizačného kódu bez zámku, ktorý sa môže skôr „točiť“ ako blokovať. SpinWait možno použiť na zníženie spotreby zdrojov vykonaním intenzívneho otáčania procesora po 10 iteračných príspevkoch, ktoré prinesú kontrolu volaním Thread.Yield a Thread.Sleep. Inými slovami, program SpinWait možno použiť na obmedzenie rotácie náročnej na procesor na pevný počet iterácií. MSDN uvádza: "System.Threading.SpinWait je ľahký typ synchronizácie, ktorý môžete použiť v scenároch na nízkej úrovni, aby ste sa vyhli nákladným kontextovým prepínačom a prechodom jadra, ktoré sú potrebné pre udalosti jadra."

Ak chcete vo svojom kóde použiť SpinWait, môžete buď využiť statickú metódu SpinUntil () štruktúry SpinWait, alebo využiť jej nestatickú metódu SpinOnce (). Nasledujúci úryvok kódu ilustruje, ako je možné použiť program SpinWait.

SpinWait spinWait = nový SpinWait ();

bool shouldSpin;

while (! shouldSpin)

{

Thread.MemoryBarrier (); spinWait.SpinOnce ();

}

$config[zx-auto] not found$config[zx-overlay] not found