Nedaloma operacija

Nedaloma operacija (angl. atomic operation) – veiksmas, kuris, net ir vykdant programą vienu metu daugeliui gijų, atliekamas visas iš karto. Programuotojui nereikia rūpintis, jog kita gija ras tik pusiau įvykdyto nedalomo veiksmo rezultatus. Taip pat reikalaujama, jog jei nedaloma operacija nepavyksta, ji turi nepavykti visa – negali likti įvykdytų pradinių nepavykusios operacijos žingsnių rezultatų.[1]

Nedalomos operacijos buvo pasiūlytos kaip greitesnė alternatyva užraktui. Jei užraktu apsaugotas bendras resursas dažnai reikalingas daugeliui gijų, jos gali daugumą laiko praleisti laukdamos užrakto eilėje. Nedalomos operacijos padeda sukurti algoritmus kuriuose daugelis gijų naudoja resursą be rakinimo. Patyrusio programuotojo rankose tai labai efektyvus metodas.[2]

Pavyzdžiui, priskyrimo sakinys (C, C++ arba Java)

 int a;
 a = 10;

yra nedalomas jei a kintamojo tipas (32 bitų sveikasis) toks, jog saugojimui skirtas bitų skaičius sutampa su procesoriaus žodžio ilgiu. Tuomet procesorius naują reikšmę greičiausiai rašys viena komanda. Kitos gijos gali aptikti arba senąją reikšmę, arba naująją – tarpinių reikšmių nebus. Nuorodų priskyrimas taip pat dažniausiai yra nedalomas veiksmas.

Tuo tarpu priskyrimo sakinys

 double a;
 a = 10.001;

gali ir nebūti nedalomas, nes slankaus kablelio skaičiui saugoti gali reikėti daugiau bitų nei telpa procesoriaus žodyje. Tada procesorius rašys naują reikšmę keletu komandų. Taigi, kitų gijų požiūriu, kintamajame a gali trumpam pasirodyti nei pradinei, nei galutinei reikšmei nelygi tarpinė reikšmė.

Priskyrimo sakinys

 long a;
 a = 10;

nėra nedalomas veiksmas 32 bitų procesoriui, tačiau paprastai yra toks 64 ar daugiau bitų procesoriams.

Padidinimas vienetu

a = a + 1;

nėra nedaloma operacija ir negali būti saugiai vykdoma keleto gijų vienu metu. Procesoriai paprastai turi komandas atminties ląstelės reikšmei vienetu padidinti, todėl veiksmas

a ++;

kai kada gali būti ir nedalomas (priklauso nuo kompiliatoriaus).

Naudojant gijų sinchronizavimo bei rakinimo metodus, nedaloma galima paversti bet kokio sudėtingumo operaciją. Pavyzdžiui, (java)

 synchronized (this) {
     a = 1;
     b = a + 1;
     c = a + b;
   }

trys priskyrimo sakiniai visi kartu yra nedaloma operacija. Tačiau ir sinchronizuota sakinių seka formaliai gali nedaloma nebūti jei nesėkmes atveju (kai metama išimtis) gali likti įvykdyta tik dalis sinchronizuotos sekcijos.

Dažniausiai naudojamos nedalomos operacijos (nenaudojant rakinimo) yre šios:[1]

  • Perskaityk kintamojo x reikšmę.
  • Priskirk kintamąjam x reikšmę.
  • Priskirk kintamąjam reikšmę, grąžink ten buvusią ankstesnę reikšmę.
  • Pridėk prie kintamojo reikšmės skirtumą y, grąžink buvusią reikšmę iki pridedant.
  • Jei x = z, priskirk x reikšmę y. Bet kuriuo atveju grąžink seną x reikšmę.

Šios operacijos vadinamos „fundamentaliosiomis“. Jų pagalba rašomi rakinimo nereikalaujantys algoritmai.

Šaltiniai redaguoti

  1. 1,0 1,1 Atomic Operations. threadingbuildingblocks.org
  2. Victor Alessandrini, in Shared Memory Application Programming, 2016. Atomic Operation. Atomic Types and Operations.[1]