Ohjelmointi

Milloin haihtuvaa avainsanaa käytetään C #: ssä

JIT (just-in-time) -kääntäjän Common Language Runtime -ohjelmassa käyttämät optimointitekniikat saattavat johtaa ennalta arvaamattomiin tuloksiin, kun .Net-ohjelma yrittää suorittaa haihtumattomia tietojen lukuja monisäikeisessä skenaariossa. Tässä artikkelissa tarkastellaan haihtuvan ja haihtumattoman muistin käytön eroja, haihtuvan avainsanan roolia C #: ssa ja kuinka haihtuvaa avainsanaa tulisi käyttää.

Annan joitain koodiesimerkkejä C #: ssä käsitteiden havainnollistamiseksi. Ymmärtääksemme kuinka haihtuva avainsana toimii, meidän on ensin ymmärrettävä, kuinka JIT-kääntäjän optimointistrategia toimii .Netissä.

Ymmärtäminen JIT-kääntäjän optimoinnista

On huomattava, että JIT-kääntäjä muuttaa osana optimointistrategiaa luku- ja kirjoitusjärjestyksen tavalla, joka ei muuta ohjelman merkitystä ja mahdollista tulosta. Tätä kuvaa alla oleva koodinpätkä.

x = 0;

x = 1;

Yllä oleva koodinpätkä voidaan muuttaa seuraavaksi - säilyttäen samalla ohjelman alkuperäinen semantiikka.

x = 1;

JIT-kääntäjä voi myös soveltaa "jatkuvan etenemisen" käsitettä seuraavan koodin optimoimiseksi.

x = 1;

y = x;

Yllä oleva koodinpätkä voidaan muuttaa seuraavaksi - jälleen säilyttäen ohjelman alkuperäinen semantiikka.

x = 1;

y = 1;

Haihtuva tai haihtumaton muistin käyttö

Nykypäivän järjestelmien muistimalli on melko monimutkainen. Sinulla on prosessorirekisterit, eri tasot välimuistit ja päämuisti, jota useat prosessorit jakavat. Kun ohjelma suoritetaan, prosessori voi tallentaa tiedot välimuistiin ja käyttää niitä sitten välimuistista, kun suorittava säike pyytää sitä. Tietojen päivitykset ja lukemiset saattavat toimia tietojen välimuistiversiota vastaan, kun taas päämuisti päivitetään myöhemmin. Tällä muistin käyttömallilla on vaikutuksia monisäikeisiin sovelluksiin.

Kun yksi ketju on vuorovaikutuksessa välimuistissa olevan datan kanssa ja toinen säie yrittää lukea samaa tietoa samanaikaisesti, toinen säie voi lukea vanhentuneen version tiedoista päämuistista. Tämä johtuu siitä, että kun haihtumattoman objektin arvo päivitetään, muutos tehdään suorittavan säikeen välimuistiin eikä päämuistiin. Kuitenkin, kun haihtuvan objektin arvo päivitetään, muutos paitsi suoritettavan säikeen välimuistissa myös välimuisti huuhdellaan päämuistiin. Ja kun haihtuvan objektin arvo luetaan, ketju päivittää välimuistin ja lukee päivitetyn arvon.

Haihtuvan avainsanan käyttäminen C #: ssä

C #: n haihtuvaa avainsanaa käytetään ilmoittamaan JIT-kääntäjälle, että muuttujan arvoa ei saa koskaan tallentaa välimuistiin, koska käyttöjärjestelmä, laitteisto tai samanaikaisesti suoritettava säie voi muuttaa sitä. Kääntäjä välttää siten muuttujan optimointien käyttöä, mikä saattaa johtaa tietoristiriitoihin, ts. Eri säikeisiin, jotka käyttävät muuttujan eri arvoja.

Kun merkitset kohteen tai muuttujan haihtuvaksi, siitä tulee ehdokas haihtuvalle lukemiselle ja kirjoittamiselle. On huomattava, että C #: ssä kaikki muistin kirjoitukset ovat epävakaita riippumatta siitä, kirjoitatko tietoja haihtuvalle vai haihtumattomalle objektille. Epäselvyys tapahtuu kuitenkin, kun luet tietoja. Kun luet tietoja, jotka eivät ole haihtuvia, suorituslanka voi saada tai ei aina saada uusimman arvon. Jos objekti on epävakaa, säie saa aina ajantasaisimman arvon.

Voit julistaa muuttujan haihtuvaksi edeltämällä sitä muuttujalla haihtuva avainsana. Seuraava koodinpätkä kuvaa tätä.

luokan ohjelma

    {

julkinen haihtuva int i;

staattinen void Main (merkkijono [] args)

        {

// Kirjoita koodi tähän

        }

    }

Voit käyttää haihtuva avainsana kaikilla viittaus-, osoitin- ja luettelotyypeillä Voit myös käyttää haihtuvaa muokkainta tavu-, lyhyt-, int-, char-, float- ja bool-tyyppien kanssa. On huomattava, että paikallisia muuttujia ei voida julistaa haihtuviksi. Kun määrität viitetyyppisen objektin haihtuvaksi, vain osoitin (32-bittinen kokonaisluku, joka osoittaa muistissa olevaan sijaintiin, johon objekti on todella tallennettu) on haihtuva, ei ilmentymän arvo. Kaksinkertainen muuttuja ei myöskään voi olla epävakaa, koska sen koko on 64 bittiä, suurempi kuin sanan koko x86-järjestelmissä. Jos sinun on tehtävä kaksinkertainen muuttuja haihtuvaksi, sinun tulisi kääri se luokan sisällä. Voit tehdä tämän helposti luomalla käärintäluokan alla olevan koodinpätkän mukaisesti.

julkinen luokka VolatileDoubleDemo

{

yksityinen haihtuva WrappedVolatileDouble volatileData;

}

julkinen luokka WrappedVolatileDouble

{

julkinen kaksinkertainen data {get; aseta; }

Huomaa kuitenkin yllä olevan koodiesimerkin rajoitus. Vaikka sinulla olisi viimeisin arvo volatileData viittausosoitinta, sinulle ei taata viimeisintä arvoa Tiedot omaisuus. Tämän ympärillä on tehtävä KäärittyHaihtuvaTupla tyyppi muuttumaton.

Vaikka epävakaa avainsana voi auttaa sinua langan turvallisuudessa tietyissä tilanteissa, se ei ole ratkaisu kaikkiin langan samanaikaisuusongelmiin. Sinun tulisi tietää, että muuttujan tai objektin merkitseminen haihtuvaksi ei tarkoita, että sinun ei tarvitse käyttää lukko-avainsanaa. Haihtuva avainsana ei korvaa lukitusavainsanaa. Se on vain auttaa sinua välttämään tietoristiriitoja, kun sinulla on useita ketjuja, jotka yrittävät käyttää samoja tietoja.

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