Secțiunea critică

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

În informatică , o secțiune critică , numită și regiune critică , este o bucată de cod care accesează o resursă partajată între mai multe fluxuri de execuție a unui sistem concurent .

Motivație

Când fluxuri diferite accesează o resursă comună în momente diferite, fiecare dintre ele își poate finaliza operațiunea (citește sau scrie) fără a fi „deranjat” de ceilalți. Dacă această condiție este întotdeauna valabilă pentru o anumită resursă, atunci se spune că citirea și scrierea pe resursa respectivă sunt operații atomice : fiecare flux poate interveni numai înainte sau după ce celălalt și-a finalizat operațiunea și nu o poate întrerupe. Termenul „atomic” este înțeles în sensul său de „unitar”, „indivizibil”. Dacă toate accesările la o resursă sunt atomice, atunci nu există probleme de sincronizare.

De exemplu, un program de copiere a fișierelor poate fi implementat cu două fire: unul care copiază octeți de pe discul sursă pe RAM și celălalt care preia simultan octeți din memorie și îi scrie pe discul de destinație. Acest program are un avantaj de viteză, deoarece suprapune timpii de latență pentru accesul pe disc, astfel încât niciunul dintre aceștia să nu fie blocat (deci neutilizat) din cauza celuilalt.

Cu toate acestea, sistemul de operare nu este conștient de faptul că fluxurile de execuție schimbă octeți: în schimb, vede doar citiri și scrieri pe discuri și în memorie și, în cel mai bun caz, poate garanta că aceste operații sunt singular atomice. Dacă cele două fire nu prevăd prezența secțiunilor critice, se poate întâmpla ca acestea să intervină simultan asupra memoriei comune și, în special, se poate întâmpla ca unul să scrie o parte a datelor în timp ce celălalt le citește în continuare. Rezultatul este că firul de lectură „vede” doar conținut parțial actualizat în memorie și, prin urmare, citește informații incorecte. Acest lucru schimbă comportamentul programului într-un mod imprevizibil, deoarece programatorul nu poate ști la ce moment vor fi executate cele două fluxuri în timpul rulării.

Soluția pentru a rezolva problema constrânge cele două fire să acceseze resursa partajată întotdeauna și numai la momente diferite. În jargon, se spune că accesele la resursă (citire și / sau scriere) se găsesc în secțiuni critice.

Implementare

Problema secțiunii critice este abordată prin proiectarea unui protocol pe care procesele îl pot utiliza pentru a coopera: fiecare flux de execuție trebuie să solicite permisiunea de a intra în propria secțiune critică, iar secțiunea de cod care face această cerere este secțiunea de intrare; secțiunea critică poate fi urmată de o secțiune de ieșire și restul codului se numește secțiune non-critică.

Modul de a defini o secțiune critică depinde de limbajul de programare utilizat, cu toate acestea mecanismul este în general același: apelați un mecanism de sincronizare (de exemplu un semafor ) la intrarea și ieșirea codului dorit în secțiunea critică. La intrare, acest mecanism verifică semaforul pentru a verifica dacă niciun alt proces nu execută codul critic. Dacă da, execuția continuă și procesul curent intră în posesia semaforului (și, prin urmare, a secțiunii critice), pentru al elibera la ieșire. Dacă nu, procesul așteaptă ca semaforul să fie șters, sau poate efectua o altă sarcină între timp. Accesul mai multor procese la o secțiune critică are în mod normal o prioritate reglementată de o coadă FIFO .

Secțiunile critice sunt de obicei puse în aplicare prin invocarea primitivelor de sistem. Dezavantajul este că API-urile acestor primitive depind exact de sistem, deci codul scris nu este portabil și trebuie rescris pentru diferite sisteme. Unele limbi rezolvă această problemă oferind o sintaxă unificată pentru definirea secțiunilor critice, pentru a evita utilizarea funcțiilor de sistem (de exemplu, Java ).

Motivul pentru care sunt definite secțiunile critice este acela de a permite accesul la o resursă în excludere reciprocă de către firele care solicită să citească sau să scrie pe resursa respectivă. Dacă un singur proces este permis să acceseze secțiunea critică la un moment dat, atunci există garanția că resursa partajată nu este niciodată modificată de mai multe procese în același timp, salvând astfel consistența informațiilor pe care le conține.

Alte informații

Secțiunile critice nu sunt necesare atunci când conținutul unei resurse partajate este imuabil, adică atunci când niciun flux de execuție nu este autorizat să scrie în resursa respectivă.

De fapt, în programarea orientată pe obiecte , se știe că obiectele imuabile (adică obiectele concepute astfel încât să nu li se permită să își schimbe starea internă odată create) sunt sigure pentru fire , adică pot fi utilizate de mai multe fluxuri de execuție fără a fi nevoie să recurgă la secțiunile critice. Folosirea obiectelor imuabile ori de câte ori este posibil face codul care le folosește mai ușor de scris și de citit. [1]

În gestionarea secțiunii critice, principalele garanții care trebuie oferite sunt trei:

  1. excludere reciprocă : dacă procesul P i rulează în secțiunea sa critică, niciun alt proces nu poate fi rulat în secțiunea sa critică.
  2. așteptare limitată: dacă un proces a solicitat deja intrarea în secțiunea sa critică, există o limită a numărului de ori în care alte procese au permisiunea de a intra în secțiunile lor critice respective înainte ca solicitarea pentru primul proces să fie acceptată. (limita maximă de așteptare după ce am exprimat voința de a intra în secțiunea critică, fără impas sau înfometare )
  3. progres: dacă nu se execută niciun proces în secțiunea sa critică, doar procesele care doresc să intre în propriul lor pot participa la decizia cu privire la cine va urma să intre în secțiunea critică și această decizie nu poate fi întârziată pe termen nelimitat.

Gestionarea secțiunilor critice din sistemele de operare implică utilizarea a două strategii principale:

  1. Kernel cu drept de preemțiune (preventiv)
  2. Kernel fără drept de prim refuz (nu preventiv)

Un kernel preventiv permite ca un proces care rulează în modul sistem să fie preventiv, amânând astfel execuția acestuia.

Notă

  1. ^ Joshua Bloch, Effective Java , ediția a II-a, Pearson Informatica, ISBN 978-88-7192-481-6 .
    "Tema 15: Obiectele imuabile sunt sigure ca fire și nu necesită sincronizare." .
Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT