Programmēšana

Labākā prakse .Net pavedienu sinhronizēšanai

Sinhronizācija ir jēdziens, kas tiek izmantots, lai neļautu vairākiem pavedieniem vienlaikus piekļūt koplietotam resursam. Varat to izmantot, lai neļautu vairākiem pavedieniem vienlaikus izmantot objekta īpašības vai metodes. Viss, kas jums jādara, ir sinhronizēt koda bloku, kas piekļūst koplietotajam resursam, vai sinhronizēt zvanus uz objekta īpašībām un dalībniekiem, lai jebkurā brīdī kritiskajā sadaļā varētu iekļūt tikai viena pavediens.

Šajā rakstā ir sniegta diskusija par jēdzieniem, kas saistīti ar sinhronizāciju un diegu drošību .Net, un par to saistīto labāko praksi.

Ekskluzīva slēdzene

Ekskluzīva bloķēšana tiek izmantota, lai nodrošinātu, ka jebkurā noteiktā brīdī kritiskajā sadaļā var iekļūt viens un tikai viens pavediens. Lai lietojumprogrammā ieviestu ekskluzīvas slēdzenes, jums jāizmanto viens no šiem.

  • Bloķēšana - tas ir sintaktiskais saīsne Monitor klases statiskajām metodēm un tiek izmantots, lai iegūtu ekskluzīvu bloķēšanu koplietotam resursam
  • Mutex - līdzīgs bloķēšanas atslēgvārdam, izņemot to, ka tas var darboties vairākos procesos
  • SpinLock - izmanto, lai iegūtu ekskluzīvu bloķēšanu kopīgotam resursam, izvairoties no pavedienu konteksta pārslēgšanas virs galvas

Lai ieviestu pavedienu drošību savās lietojumprogrammās, varat izmantot monitora klases statiskās metodes vai bloķēšanas atslēgvārdu. Lai novērstu vienlaicīgu piekļuvi koplietotam resursam, var izmantot gan Monitora klases statiskos locekļus, gan bloķēšanas atslēgvārdus. Bloķēšanas atslēgvārds ir tikai saīsnes veids sinhronizācijas ieviešanai. Tomēr, ja jums ir jāveic sarežģītas darbības vairāku pavedienu lietojumprogrammā, Monitora klases metodes Wait () un Pulse () var būt noderīgas.

Šis koda fragments parāda, kā sinhronizāciju var ieviest, izmantojot klases Monitoru.

privāts statisks tikai lasāms objekts lockObj = jauns objekts ();

       static void Main (virkne [] args)

        {

Monitor. Ievadiet (lockObj);

                       mēģiniet

            {

// Daži kodi

            }

            beidzot

            {

Monitor.Exit (lockObj);

            }

        }

Ekvivalents kods, izmantojot atslēgas atslēgu, izskatīsies līdzīgi šim:

    privāts statisks tikai lasāms objekts lockObj = jauns objekts ();

static void Main (virkne [] args)

        {  

mēģiniet

            {

slēdzene (lockObj)

                {

// Daži kodi

                }             

            }

beidzot

            {

// Šeit varat atbrīvot visus resursus

            }

        }

Jūs varat izmantot Mutex klases priekšrocības, lai ieviestu sinhronizāciju, kas var aptvert visus procesus. Ņemiet vērā, ka līdzīgi kā bloķēšanas paziņojumā, Mutex iegūto slēdzeni var atbrīvot tikai no tā paša pavediena, kas tika izmantots slēdzenes iegūšanai. Slēdzeņu iegūšana un atbrīvošana, izmantojot Mutex, ir salīdzinoši lēnāka nekā to pašu darot, izmantojot atslēgu.

SpinLock galvenā ideja ir samazināt izmaksas, kas saistītas ar pārslēgšanos starp pavedieniem kontekstā - ja pavediens var kādu laiku gaidīt vai griezties, līdz tas var iegūt bloķēšanu koplietotajā resursā, var izvairīties no pieskaitāmajām izmaksām, kas saistītas ar pārslēgšanos starp pavedieniem. . Kad kritiskā sadaļa veic minimālu darbu, tas var būt labs kandidāts SpinLock.

Neekskluzīva slēdzene

Lai ierobežotu vienlaicīgumu, varat izmantot neekskluzīvas bloķēšanas priekšrocības. Lai ieviestu neekskluzīvas slēdzenes, varat izmantot kādu no šīm iespējām.

  • Semafors - tiek izmantots, lai ierobežotu to pavedienu skaitu, kuriem vienlaikus var būt piekļuve kopīgotam resursam. Būtībā to izmanto, lai vienlaikus ierobežotu konkrēta koplietojamā resursa patērētāju skaitu.
  • SemaphoreSlim - ātra, viegla alternatīva Semaphore klasei, lai ieviestu neekskluzīvas slēdzenes.
  • ReaderWriterLockSlim - klase ReaderWriterLockSlim tika ieviesta .Net Framework 3.5 kā ReaderWriterLock klases aizstājēja.

Varat izmantot klasi ReaderWriterLockSlim, lai iegūtu koplietojamā resursa neekskluzīvu slēdzeni, kurai būtu nepieciešami bieži lasījumi, bet reti atjauninājumi. Tātad, tā vietā, lai savstarpēji izslēdzoša koplietojamā resursa bloķēšana, kurai nepieciešama bieža lasīšana un reti atjauninājumi, varat izmantot šo klasi, lai iegūtu koplietojamā resursa lasīšanas bloķēšanu un ekskluzīvu rakstīšanas bloķēšanu.

Strupceļi

Lai sinhronizētu lietojumprogrammu, jums jāizvairās no bloķēšanas priekšraksta izmantošanas vai izmantot tādus izteikumus kā lock (this), jo tas var izraisīt strupceļus. Ņemiet vērā, ka strupceļš var rasties arī tad, ja ilgāk turat bloķēšanu, kas iegūta kopīgotajā resursā. Bloķēšanas paziņojumos nevajadzētu izmantot nemaināmus veidus. Piemēram, jums vajadzētu izvairīties no virknes objekta kā atslēgas izmantošanas bloķēšanas paziņojumā. Jums vajadzētu izvairīties no bloķēšanas paziņojuma izmantošanas publiskā tipā - laba prakse ir bloķēt privātus vai aizsargātus objektus, kas nav internēti. Būtībā strupceļš rodas tad, kad vairāki pavedieni gaida viens otru, lai atbrīvotu bloķēšanu koplietotajā resursā. Lai uzzinātu vairāk par strupceļiem, varat atsaukties uz šo MSDN rakstu.

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