Šis raksts ir mašīntulkošanas spoguļraksts, lūdzu, noklikšķiniet šeit, lai pārietu uz oriģinālo rakstu.

Skats: 46741|Atbildi: 7

[Avots] Gaistošs vs. Bloķēts pret bloķēšanu

[Kopēt saiti]
Publicēts 27.08.2018 14:40:35 | | |
Pieņemsim, ka ir klase, kas satur publisku int skaitītāja lauku, kuram var piekļūt vairāki pavedieni, un šis skaitlis tikai palielināsies vai samazināsies.

Pievienojot šo lauku, kuras no šīm shēmām ir jāizmanto un kāpēc?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment(ref this.counter);
  • Skaitītāja piekļuves modifikatora maiņa uz publisku svārstīgu


Sliktākais (neviens no tiem faktiski nedarbojas)

Skaitītāja piekļuves modifikatora maiņa uz publisku svārstīgu

Šī pieeja faktiski nav droša, un jautājums par gaistošo ir tas, ka vairāki pavedieni, kas darbojas uz vairākiem CPU, bufera datus un pārkārto izpildītās instrukcijas.

Ja tas nav gaistošs, kad CPU A palielinās par vērtību, CPU B ir jāgaida, lai redzētu palielināto vērtību, kas var radīt problēmas.

Ja tas ir svārstīgs, tas nodrošina, ka abi procesori vienlaicīgi redz vienu un to pašu vērtību. Bet tas neizvairās no transversālām lasīšanas un rakstīšanas operācijām.

Vērtības pievienošana mainīgajam faktiski aizņem trīs soļus

1. Lasīšana, 2. Pievienot 3. Rakstīt

Pieņemsim, ka pavediens A nolasa skaitītāja vērtību kā 1 un nav gatavs palielināt, tad pavediens B arī nolasa skaitītāja vērtību kā 1, un tad abi pavedieni sāk veikt pakāpeniskas un rakstīšanas operācijas. Galīgā skaitītāja vērtība ir 2. Tas nav pareizi, abi pavedieni ir veikuši palielināšanas operāciju, un pareizajam rezultātam jābūt 3. Tātad marķēt to kā gaistošo ir vienkārši nedroši.

Tas ir labāk

lock(this.locker) this.counter++;

Tādā veidā tas ir droši (protams, neaizmirstiet bloķēt visur, kur vēlaties piekļūt šim.skaitītājs). Tas neļauj jebkuram citam pavedienam izpildīt bloķēto kodu. Un tas arī novērš iepriekš minēto vairāku CPU instrukciju secības problēmu. Problēma ir tā, ka bloķēšana ir lēna, un, ja izmantojat bloķēšanu citās nesaistītās vietās, tā var bloķēt citus pavedienus.

Labākais

Interlocked.Increment(ref this.counter);

Tas ir droši un ļoti efektīvi. Tas veic lasīšanu, palielināšanu, rakstīšanu trīs operācijas vienā atomā, nepārtraucot vidū. Tā kā tas neietekmē citu kodu, jums nav jāatceras slēdzenes citur. Un tas ir arī ļoti ātrs (kā saka MSDN, mūsdienu procesoros bieži vien tā ir tikai instrukcija).

Bet es neesmu pilnīgi pārliecināts, vai tas var atrisināt arī CPU instrukciju pasūtīšanas problēmu, vai arī tas ir jāizmanto kopā ar gaistošo un šo pieaugumu.

Papildinājums: Kādas problēmas labi atrisina gaistošs?

Tā kā gaistošs nevar novērst daudzpavedienu, ko tas var darīt? Labs piemērs ir tas, ka jums ir divi pavedieni, viens vienmēr raksta mainīgajā, pieņemsim, ka šis mainīgais ir queneLength, bet otrs vienmēr nolasa datus no šī mainīgā. Ja queueLenght nav svārstīgs, pavediens A var nolasīt 5 reizes, bet pavediens B var redzēt aizkavētus datus vai pat datus nepareizā secībā. Viens risinājums ir izmantot slēdzeni, bet šajā gadījumā varat izmantot arī gaistošus. Tas nodrošina, ka pavediens B vienmēr redz jaunākos datus, ko raksta pavediens A, bet šī loģika darbojas tikai tad, ja jūs to nelasāt, kad to rakstāt, un ja jūs to nerakstāt, kad to lasāt. Kad vairāki pavedieni vēlas veikt lasīšanas, modificēšanas un rakstīšanas operācijas, jums jāizmanto bloķēts vai bloķēts.





Iepriekšējo:Java MD5 šifrēšanas metode
Nākamo:Linq ievieš SQL ne un nosacītos vaicājumos
Publicēts 29.08.2018 16:21:42 |
Sveiki, kods, ko jūs darījāt agrāk, kas apvieno augstas diagrammas sakrautas histogrammas un urbjamas histogrammas? Es gribētu jautāt, vai jūs varat nosūtīt kodu, ko var rediģēt https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light saskarnē?
Publicēts 29.08.2018 16:22:13 |
Viss tīkls ir tikai jūsu resurss.
Publicēts 29.08.2018 16:22:55 |
Jo iepriekšējie pirms 90 gadiem nevarēja atstāt ziņu. tātad
Publicēts 29.08.2018 16:40:40 |
Vai ir ērti pievienot kontaktinformāciju? Konsultējieties ar jums
 Saimnieks| Publicēts 15.09.2018 13:10:16 |
privāts statisks int safeInstanceCount = 0; Darbs ar atomiem
System.Threading.Interlocked.Increment(ref safeInstanceCount); Pašpieaugums 1
System.Threading.Interlocked.Decrement(ref safeInstanceCount); Pašmīnus 1
Publicēts 21.05.2020 16:43:54 |
Atbalstiet īpašnieku, lai kopīgotu
 Saimnieks| Publicēts 11.06.2020 15:00:16 |
1. Koncepcija

Vairāku pavedienu vidē operācijas, kuras nepārtrauc pavedienu plānošanas mehānismi; Kad šī darbība sākas, tā darbojas līdz beigām, bez konteksta slēdža (pārslēgšanās uz citu pavedienu).

2. Klase

System.Threading.Interlocked statiskā klase

3. Biežāk izmantotās funkcijas (skatīt pārējās)

1. publiskais statiskais int Decrement (ref int atrašanās vieta); Decrinējiet norādītā mainīgā vērtību atomu operācijas veidā un saglabājiet rezultātu

Ekvivalents lock(obj){i--; }

2.publiskais statiskais int Increment (ref int atrašanās vieta); Palieliniet norādītā mainīgā vērtību atomu operācijas veidā un saglabājiet rezultātu

Ekvivalents lock(obj){i++; }
Atruna:
Visa programmatūra, programmēšanas materiāli vai raksti, ko publicē Code Farmer Network, ir paredzēti tikai mācību un pētniecības mērķiem; Iepriekš minēto saturu nedrīkst izmantot komerciāliem vai nelikumīgiem mērķiem, pretējā gadījumā lietotājiem ir jāuzņemas visas sekas. Informācija šajā vietnē nāk no interneta, un autortiesību strīdiem nav nekāda sakara ar šo vietni. Iepriekš minētais saturs ir pilnībā jāizdzēš no datora 24 stundu laikā pēc lejupielādes. Ja jums patīk programma, lūdzu, atbalstiet oriģinālu programmatūru, iegādājieties reģistrāciju un iegūstiet labākus oriģinālus pakalpojumus. Ja ir kādi pārkāpumi, lūdzu, sazinieties ar mums pa e-pastu.

Mail To:help@itsvse.com