Tämä artikkeli on konekäännöksen peiliartikkeli, klikkaa tästä siirtyäksesi alkuperäiseen artikkeliin.

Näkymä: 46741|Vastaus: 7

[Lähde] Epävakaa vs. Lukittu vs. lukko

[Kopioi linkki]
Julkaistu 27.8.2018 14.40.35 | | |
Oletetaan, että on olemassa luokka, joka sisältää julkisen älykkyyslaskurin, johon pääsee käsiksi useilla säikeillä, ja tämä luku vain kasvaa tai pienenee.

Kun tätä kenttää lisätään, mitä seuraavista kaavoista tulisi käyttää, ja miksi?

  • lukitse(this.locker) this.counter++;
  • Interlocked.Increment (viitte tämä.laskuri);
  • Muuta laskurin pääsyn modifikaattori julkiseksi volatiiliksi


Pahin (mikään niistä ei oikeasti toimi)

Muuta laskurin pääsyn modifikaattori julkiseksi volatiiliksi

Tämä lähestymistapa ei itse asiassa ole lainkaan turvallinen, ja epävakaan ongelman pointti on, että useat säikeet, jotka toimivat useilla suorittimilla, puskuroivat dataa ja järjestävät suoritetut käskyt uudelleen.

Jos se ei ole volatiili, CPU A nousee arvolla, CPU B:n täytyy odottaa hetki nähdäkseen arvon, mikä voi aiheuttaa ongelmia.

Jos se on epävakaa, se varmistaa, että molemmat suorittimet näkevät saman arvon samaan aikaan. Mutta se ei estä poikkileikkaavia luku- ja kirjoitustoimintoja.

Muuttujan arvon lisääminen vaatii itse asiassa kolme vaihetta

1. Lukeminen, 2. Lisää 3. Kirjoita

Oletetaan, että säie A lukee laskurin arvon arvoksi 1 eikä ole valmis kasvamaan, silloin säie B lukee laskurin arvon arvoksi 1, ja molemmat säikeet alkavat suorittaa inkrementaalisia ja kirjoitusoperaatioita. Viimeisen laskurin arvo on 2. Tämä ei pidä paikkaansa, molemmat säikeet ovat tehneet suurennusoperaation, ja oikea tulos pitäisi olla 3. Joten sen leimaaminen epävakaaksi on yksinkertaisesti vaarallista.

Se on parempi

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

Näin se on turvallista (muista lukita kaikki, joihin haluat päästä tähän .counteriin, tietenkin). Se estää muita säikeitä suorittamasta lukittua koodia. Se myös estää edellä mainitun moniprosessorisen käskyjärjestysongelman. Ongelma on, että lukitus on hidas suorituskyvyltään, ja jos käytät lukkoa muissa eri paikoissa, se voi estää muut säikeet.

Paras

Interlocked.Increment (viitte tämä.laskuri);

Tämä on turvallista ja erittäin tehokasta. Se suorittaa luku-, kasvatus- ja kirjoitustoimintoja yhdessä atomissa keskeyttämättä keskellä. Koska se ei vaikuta muuhun koodiin, sinun ei tarvitse muistaa lukkoja muualla. Ja se on myös hyvin nopea (kuten MSDN sanoo, nykyprosessoreissa se on usein vain käsky).

Mutta en ole täysin varma, voiko se ratkaista myös CPU:n käskyjärjestysongelman, vai pitääkö sitä käyttää yhdessä volatilen ja tämän lisäyksen kanssa.

Lisäravinne: Mitä ongelmia Volatile ratkaisee hyvin?

Koska Volatile ei voi estää monisäikeistämistä, mitä se voi tehdä? Hyvä esimerkki on, että sinulla on kaksi säikettä, joista toinen kirjoittaa aina muuttujalle, sanotaan että tämä muuttuja on queneLength, ja toinen aina lukee dataa tästä muuttujasta. Jos queueLenght ei ole volatiili, säie A voi lukea 5 kertaa, mutta säie B saattaa nähdä viivästyneitä tietoja tai jopa väärässä järjestyksessä. Yksi ratkaisu on käyttää lukkoa, mutta tässä tapauksessa voit käyttää myös volatilea. Tämä varmistaa, että säie B näkee aina viimeisimmän datan, jonka säie A on kirjoittanut, mutta tämä logiikka toimii vain, jos et lue sitä kirjoittaessasi, ja jos et kirjoita sitä lukiessasi. Kun useat säikeet haluavat tehdä luku-muokkaa-kirjoitusoperaatioita, sinun täytyy käyttää Interlocked- tai Lock-toimintoja.





Edellinen:Java MD5 -salausmenetelmä
Seuraava:Linq toteuttaa ehdolliset kyselyt SQL:ssä
Julkaistu 29.8.2018 16.21.42 |
Hei, se koodi, jonka teit aiemmin, joka yhdistää highchart-pinotut histogrammit ja porattavat histogrammit? Haluaisin kysyä, voisitko lähettää koodin, jota voi muokata https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light käyttöliittymässä?
Julkaistu 29.8.2018 16.22.13 |
Koko verkosto on vain resurssisi.
Julkaistu 29.8.2018 16.22.55 |
Koska edelliset 90 vuotta sitten ei voinut jättää viestiä. joten
Julkaistu 29.8.2018 16.40.40 |
Onko kätevää lisätä yhteystiedot? Keskustelen kanssasi
 Vuokraisäntä| Julkaistu 15.9.2018 13.10.16 |
yksityinen staattinen int safeInstanceCount = 0; Toimi atomien kanssa
System.Threading.Interlocked.Increment (viite safeInstanceCount); Itse-kasvu 1
System.Threading.Interlocked.Decrement (viite safeInstanceCount); Itse-miinus 1
Julkaistu 21.5.2020 16.43.54 |
Tue omistajaa jakamaan
 Vuokraisäntä| Julkaistu 11.6.2020 15.00.16 |
1. Konsepti

Monisäikeisessä ympäristössä operaatioita, joita säikeiden ajoitusmekanismit eivät keskeytä; Kun tämä operaatio alkaa, se jatkuu loppuun asti ilman kontekstin vaihtoa (vaihtoa toiseen säikeeseen) välissä.

2. Luokka

System.Threading.Interlocked staattinen luokka

3. Yleisesti käytetyt funktiot (katso loput)

1. julkinen staattinen älykkyys Vähennys (viite int sijainti); Decrin määritellyn muuttujan arvo atomioperaationa ja tallenna tulos

Ekvivalentti lock(obj){i--; }

2. julkinen staattinen int Increment (viite int sijainti); Lisää määritellyn muuttujan arvoa atomioperaationa ja tallenna tulos

Ekvivalentti lock(obj){i++; }
Vastuuvapauslauseke:
Kaikki Code Farmer Networkin julkaisemat ohjelmistot, ohjelmamateriaalit tai artikkelit ovat tarkoitettu vain oppimis- ja tutkimustarkoituksiin; Yllä mainittua sisältöä ei saa käyttää kaupallisiin tai laittomiin tarkoituksiin, muuten käyttäjät joutuvat kantamaan kaikki seuraukset. Tämän sivuston tiedot ovat peräisin internetistä, eikä tekijänoikeuskiistat liity tähän sivustoon. Sinun tulee poistaa yllä oleva sisältö kokonaan tietokoneeltasi 24 tunnin kuluessa lataamisesta. Jos pidät ohjelmasta, tue aitoa ohjelmistoa, osta rekisteröityminen ja hanki parempia aitoja palveluita. Jos rikkomuksia ilmenee, ota meihin yhteyttä sähköpostitse.

Mail To:help@itsvse.com