Programavimas

Kada naudoti nepastovų raktinį žodį C #

Optimizavimo metodai, kuriuos JIT („just-in-time“) kompiliatorius naudoja „Common Language Runtime“, gali sukelti nenuspėjamų rezultatų, kai „.Net“ programa bando nepastoviai skaityti duomenis pagal daugiagijį scenarijų. Šiame straipsnyje mes apžvelgsime skirtumus tarp nepastovios ir nepastovios atminties prieigos, nepastovaus raktinio žodžio vaidmens C # ir kaip turėtų būti naudojamas nepastovus raktinis žodis.

Pateiksiu keletą kodų pavyzdžių C #, kurie iliustruoja sąvokas. Norėdami suprasti, kaip veikia nepastovus raktinis žodis, pirmiausia turime suprasti, kaip JIT kompiliatoriaus optimizavimo strategija veikia .Net.

Suprasti JIT kompiliatoriaus optimizavimą

Reikėtų pažymėti, kad JIT kompiliatorius, vykdydamas optimizavimo strategiją, pakeis skaitymo ir rašymo tvarką taip, kad nepakeistų programos prasmės ir galimo rezultato. Tai iliustruojama toliau pateiktame kodo fragmente.

x = 0;

x = 1;

Pirmiau pateiktą kodo fragmentą galima pakeisti tokiu, išlaikant pradinę programos semantiką.

x = 1;

JIT kompiliatorius taip pat gali pritaikyti sąvoką, vadinamą „pastovus sklidimas“, kad optimizuotų šį kodą.

x = 1;

y = x;

Pirmiau pateiktą kodo fragmentą galima pakeisti tokiu, kad išsaugotumėte pradinę programos semantiką.

x = 1;

y = 1;

Nepastovi ir nepastovi atminties prieiga

Šiuolaikinių sistemų atminties modelis yra gana sudėtingas. Turite procesorių registrus, įvairaus lygio talpyklas ir pagrindinę atmintį, kurią bendrina keli procesoriai. Kai jūsų programa vykdoma, procesorius gali talpinti duomenis talpykloje ir tada pasiekti šiuos duomenis iš talpyklos, kai to reikalauja vykdomoji gija. Šių duomenų atnaujinimai ir skaitymai gali būti suderinami su talpykloje saugoma duomenų versija, o pagrindinė atmintis bus atnaujinta vėliau. Šis atminties naudojimo modelis turi pasekmių daugialypėms programoms.

Kai viena gija sąveikauja su talpyklos duomenimis, o antroji gija bando tuos pačius duomenis skaityti vienu metu, antroji gija gali skaityti pasenusią duomenų versiją iš pagrindinės atminties. Taip yra todėl, kad atnaujinus nepastovaus objekto vertę, pakeitimas atliekamas vykdančiosios gijos talpykloje, o ne pagrindinėje atmintyje. Tačiau atnaujinus nepastovaus objekto vertę, vykdomasis siūlas pakeičiamas ne tik talpykloje, bet ir ši talpykla ištrinama į pagrindinę atmintį. Kai nuskaitoma nepastovaus objekto vertė, gija atnaujina talpyklą ir nuskaito atnaujintą vertę.

Nepastovaus raktinio žodžio naudojimas C #

Nepastovus raktinis žodis C # naudojamas informuoti JIT kompiliatorių, kad kintamojo reikšmė niekada neturėtų būti talpykloje, nes ją gali pakeisti operacinė sistema, aparatinė įranga arba tuo pačiu metu vykdoma gija. Taigi kompiliatorius vengia naudoti bet kokius kintamojo optimizavimus, kurie gali sukelti duomenų konfliktus, t.

Kai pažymite objektą ar kintamąjį kaip nepastovų, jis tampa kandidatu į nepastovius skaitymus ir rašymą. Reikėtų pažymėti, kad C # visi atminties įrašai yra nepastovūs, neatsižvelgiant į tai, ar duomenis rašote nepastoviam, ar nepastoviam objektui. Tačiau neaiškumas įvyksta, kai skaitote duomenis. Kai skaitote nepastovius duomenis, vykdymo gija gali arba ne visada gauna naujausią vertę. Jei objektas yra nepastovus, gija visada gauna naujausią vertę.

Kintamąjį galite paskelbti nepastoviu, prieš jį pažymėdami nepastovus raktinis žodis. Tai iliustruoja šis kodo fragmentas.

klasės programa

    {

public volatile int i;

static void Main (string [] args)

        {

// Čia parašykite savo kodą

        }

    }

Galite naudoti nepastovus raktinis žodis su nuorodų, žymeklių ir enum tipais. Nepastovų modifikatorių taip pat galite naudoti su baitų, trumpųjų, int, char, float ir bool tipais. Reikėtų pažymėti, kad vietinių kintamųjų negalima paskelbti nepastoviais. Kai nurodote, kad nuorodos tipo objektas yra nepastovus, nepastovus yra tik žymeklis (32 bitų sveikasis skaičius, nurodantis atminties vietą, kurioje objektas iš tikrųjų saugomas), o ne egzemplioriaus vertė. Be to, dvigubas kintamasis negali būti nepastovus, nes jis yra 64 bitų dydžio, didesnis nei žodžio dydis x86 sistemose. Jei jums reikia padaryti dvigubą kintamąjį lakų, turėtumėte jį apvynioti klasės viduje. Tai galite lengvai padaryti sukurdami įvyniojimo klasę, kaip parodyta žemiau esančiame kodo fragmente.

viešoji klasė „VolatileDoubleDemo“

{

privatūs nepastovūs „WrappedVolatileDouble volatileData“;

}

viešoji klasė WrappedVolatileDouble

{

public double data {get; rinkinys; }

Tačiau atkreipkite dėmesį į pirmiau minėto kodo pavyzdžio apribojimą. Nors turėtumėte naujausią nepastovusDuomenys nuorodos rodyklę, jums negarantuojama naujausia Duomenys nuosavybė. Darbas aplink tai yra padaryti WrappedVolatileDouble tipas nekintamas.

Nors nepastovus raktinis žodis gali padėti jums užtikrinti siūlų saugumą tam tikrose situacijose, jis nėra visų siūlų lygiagrečių problemų sprendimas. Turėtumėte žinoti, kad kintamojo ar objekto žymėjimas kaip nepastovus nereiškia, kad nereikia naudoti raktinio žodžio. Nepastovus raktinis žodis nepakeičia raktinio žodžio. Tai tik tam, kad padėtų išvengti duomenų konfliktų, kai turite keletą gijų, bandančių pasiekti tuos pačius duomenis.