Programmering

Mine to cent på SpinLock i .Net

Forestil dig en situation, hvor en tråd forsøger at få adgang til en delt ressource, men ressourcen allerede er låst, så tråden skal vente, indtil låsen frigøres. Her er hvor trådsynkronisering kommer i spil. Trådsynkronisering bruges til at forhindre flere tråde i at få adgang til en delt ressource samtidigt. Microsoft .Net Framework understøtter en række synkroniseringsprimitiver, der kan bruges til at kontrollere trådadfærd og undgå race-forhold. Mutex og Spinlock er to populære synkroniseringsmekanismer, der bruges til at synkronisere adgang til en delt ressource.

En SpinLock er et alternativ til at blokere synkronisering. SpinLock (også kendt som "Busy Waiting") er en mekanisme, der kan bruges til at få en tråd til at forsøge at få en lås i en løkke, indtil den kan få adgang til ressourcen. Bemærk, at SpinLock kan udføre hurtigere sammenlignet med Mutex, da kontekstskift er reduceret. Du bør dog kun bruge SpinLocks, hvis det kritiske afsnit skal udføre en minimal mængde arbejde, dvs. SpinLock holdes i en meget kort periode. SpinLocks foretrækkes normalt i symmetriske multiprocessorsystemer frem for konstant afstemning efter tilgængelighed af en ressource i stedet for kontekstskiftere.

Hvad er SpinLock, og hvorfor er det nødvendigt?

SpinLock udfører travlt med at vente og kan tilbyde bedre ydeevne, når de bruges i multi-core systemer, især når det er billigt at vente i en løkke og samle en ressource i stedet for at blokere for den. Dette er især nyttigt, når låsetiden er kortvarig. Med andre ord kan du drage fordel af SpinLock i multi-core-systemer for at reducere omkostningerne, der er involveret i kontekstskift, hvis tiden, der skal bruges inde i den kritiske sektion, er lille. Et kritisk afsnit kan defineres som en datastruktur eller en ressource, der deles af flere tråde, men en og samme tråd kan have adgang til den på et givet tidspunkt.

Det skal bemærkes, at at holde SpinLock i længere tid simpelthen ville være spild af systemets ressourcer og skadeligt for applikationens ydeevne. I det væsentlige, hvis du forventer, at blokeringen har en betydelig varighed, bør SpinLock aldrig bruges - brug kun SpinLock, når låsetiden har en forholdsvis lille varighed.

SpinLock bruges typisk, når man arbejder med afbrydelser for at udføre travlt med at vente inde i en løkke, indtil ressourcen er gjort tilgængelig. SpinLock får ikke tråden til at blive forhindret, men snarere snurrer den, indtil lås på ressourcen frigives.

Programmering af SpinLock i .Net

Bemærk, at en SpinLock er defineret som en struktur i .Net, dvs. den er defineret som en værditype af ydeevneårsager. Derfor, hvis du passerer en SpinLock-forekomst, skal du videregive den med reference og ikke efter værdi. I dette afsnit undersøger vi, hvordan vi kan programmere SpinLock i .Net. For at implementere SpinLock i .Net skal du udnytte SpinLock-klassen, der er tilgængelig i System.Threading-navneområdet.

Følgende kodeliste viser, hvordan du kan bruge SpinLock i .Net.

SpinLock spinLock = ny SpinLock (sand);

bool isLocked = false;

prøve

{

spinLock.Enter (ref isLocked);

// Skriv din sædvanlige kode her

}

langt om længe

{

hvis (er låst)

spinLock.Exit ();

}

SpinWait

Bemærk, at ligesom SpinLock er SpinWait også en struktur og ikke en klasse. I lighed med SpinLock kan du bruge SpinWait til at skrive låsefri synkroniseringskode, der kan "spinde" i stedet for at blokere. SpinWait kan bruges til at reducere ressourceforbruget ved at udføre CPU-intensiv centrifugering i 10 iterationsindlæg, som det giver kontrol ved at kalde Thread.Yield og Thread.Sleep. Med andre ord kan SpinWait bruges til at begrænse CPU-intensiv centrifugering til et fast antal iterationer. MSDN siger: "System.Threading.SpinWait er en letvægtssynkroniseringstype, som du kan bruge i scenarier på lavt niveau for at undgå de dyre kontekstomskiftere og kernetransitioner, der kræves til kernehændelser."

For at bruge SpinWait i din kode kan du enten udnytte den statiske metode SpinUntil () i SpinWait-strukturen eller drage fordel af dens ikke-statiske metode SpinOnce (). Følgende kodestykke illustrerer, hvordan SpinWait kan bruges.

SpinWait spinWait = ny SpinWait ();

bool shouldSpin;

mens (! shouldSpin)

{

Tråd.MemoryBarrier (); spinWait.SpinOnce ();

}

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