Programmēšana

Mani divi centi par SpinLock .Net

Iedomājieties situāciju, kurā pavediens mēģina iegūt piekļuvi koplietotam resursam, bet resurss jau ir bloķēts, tāpēc pavedienam ir jāgaida, līdz bloķēšana tiek atbrīvota. Šeit tiek parādīta pavedienu sinhronizācija. Vītņu sinhronizācija tiek izmantota, lai neļautu vairākiem pavedieniem vienlaikus piekļūt koplietotam resursam. Microsoft .Net Framework nodrošina atbalstu virknei sinhronizācijas primitīvu, kurus var izmantot, lai kontrolētu pavedienu uzvedību un izvairītos no sacensību apstākļiem. Mutex un Spinlock ir divi populāri sinhronizācijas mehānismi, kurus izmanto, lai sinhronizētu piekļuvi koplietotam resursam.

SpinLock ir alternatīva sinhronizācijas bloķēšanai. SpinLock (pazīstams arī kā "Aizņemta gaidīšana") ir mehānisms, ko var izmantot, lai pavediens mēģinātu iegūt bloķēšanas gaidīšanu ciklā, līdz tas var piekļūt resursam. Ņemiet vērā, ka SpinLock var darboties ātrāk, salīdzinot ar Mutex, jo tiek samazināta konteksta maiņa. Tomēr jums vajadzētu izmantot SpinLocks tikai tad, ja kritiskajā sadaļā paredzēts veikt minimālu darba apjomu, t.i., SpinLock tiek turēts ļoti īsu laika periodu. SpinLocks parasti dod priekšroku simetriskās daudzprocesoru sistēmās, lai pastāvīgi aptaujātu par resursa pieejamību konteksta slēdžu vietā.

Kas ir SpinLock un kāpēc tas ir vajadzīgs?

SpinLock veic aizņemtu gaidīšanu un var piedāvāt labāku sniegumu, ja to izmanto daudzkodolu sistēmās, it īpaši, ja ir lēti gaidīt ciklā un apvienot resursu, nevis bloķēt to. Tas ir īpaši noderīgi, ja bloķēšanas aizturēšanas laiks ir īss. Citiem vārdiem sakot, jūs varat izmantot SpinLock priekšrocības daudzkodolu sistēmās, lai samazinātu pieskaitāmās izmaksas, kas saistītas ar konteksta maiņu, ja kritiskajā sadaļā pavadāmais laiks ir mazs. Kritisko sadaļu var definēt kā datu struktūru vai resursu, kuru koplieto vairāki pavedieni, bet vienam un tikai vienam pavedienam tam var būt piekļuve jebkurā noteiktā brīdī.

Jāatzīmē, ka SpinLock turēšana ilgāku laiku vienkārši iztērētu sistēmas resursus un kaitētu lietojumprogrammas veiktspējai. Būtībā, ja jūs domājat, ka bloķēšanai ir ievērojams ilgums, SpinLock nekad nevajadzētu izmantot - izmantojiet SpinLock tikai tad, ja bloķēšanas aizturēšanas laiki ir pietiekami maza.

SpinLock parasti izmanto, strādājot ar pārtraukumiem, lai veiktu aizņemtu gaidīšanu cikla laikā, līdz resurss ir pieejams. SpinLock neizraisa pavediena aizspiešanu, drīzāk tas turpina griezties, līdz tiek atbrīvota resursa bloķēšana.

SpinLock programmēšana .Net

Ņemiet vērā, ka SpinLock ir definēts kā .net tīkls, t.i., veiktspējas apsvērumu dēļ tas tiek definēts kā vērtības tips. Tādējādi, ja jūs ejat ap SpinLock instanci, jums tas jānodod ar atsauci, nevis pēc vērtības. Šajā sadaļā mēs izpētīsim, kā mēs varam ieprogrammēt SpinLock .Net. Lai ieviestu SpinLock .Net, jums būs jāizmanto sistēmā SpinLock pieejamās priekšrocības. Vārdvietas vītne.

Šis kodu saraksts parāda, kā SpinLock var izmantot .Net.

SpinLock spinLock = jauns SpinLock (patiess);

bool isLocked = nepatiesa;

mēģiniet

{

spinLock.Enter (atsaite ir bloķēta);

// Šeit pierakstiet savu parasto kodu

}

beidzot

{

ja (ir bloķēts)

spinLock.Exit ();

}

SpinWait

Ņemiet vērā, ka tāpat kā SpinLock, arī SpinWait ir struktūra, nevis klase. Līdzīgi kā SpinLock, jūs varat izmantot SpinWait, lai rakstītu bloķēšanas bezmaksas sinhronizācijas kodu, kas var "griezties", nevis bloķēt. SpinWait var izmantot, lai samazinātu resursu patēriņu, veicot intensīvu centrālā procesora vērpšanu 10 atkārtojumu ierakstiem, kurus tā kontrolēs, izsaucot Thread.Yield un Thread.Sleep. Citiem vārdiem sakot, SpinWait var izmantot, lai ierobežotu centrālā procesora intensīvu vērpšanu līdz fiksētam atkārtojumu skaitam. MSDN norāda: "System.Threading.SpinWait ir viegls sinhronizācijas veids, kuru varat izmantot zema līmeņa scenārijos, lai izvairītos no dārgiem konteksta komutatoriem un kodola pārejām, kas nepieciešami kodola notikumiem."

Lai savā kodā izmantotu SpinWait, varat vai nu izmantot SpinWait struktūras statisko metodi SpinUntil (), vai arī izmantot tās SpinOnce () statiskās metodes priekšrocības. Šis koda fragments parāda, kā SpinWait var izmantot.

SpinWait spinWait = jauns SpinWait ();

bool shouldSpin;

kamēr (! shouldSpin)

{

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

}