Semafor (informatică)

Un semafor este o variabilă (sau un tip de date abstract) împărtășit de diferiți „actori”, care asigură faptul că aceștia îl pot accesa doar secvențial prin operații atomice și este metoda utilizată în mod obișnuit pentru a restricționa accesul la resursele partajate (de exemplu, spațiul de stocare) și sincronizează procesele într-un mediu de programare simultan . Semaforul a fost inventat de Edsger Dijkstra și utilizat pentru prima dată în sistemul de operare .

Semaforele oferă cea mai comună soluție la faimoasa problemă a „  Filozofilor de masă  ”, deși nu evită blocaje (sau blocaje ). Pentru a putea exista sub formă de software, acestea necesită o implementare hardware (la nivel de microprocesor ), făcând posibilă testarea și modificarea variabilei protejate în timpul unui ciclu neîntrerupt. Într-adevăr, într-un context de multiprogramare , nu putem risca să vedem variabila modificată de un alt proces imediat după ce procesul curent tocmai a testat-o ​​și înainte ca aceasta să o modifice.

Operațiuni

Cele trei operații acceptate sunt Init, Pși V.

Piar Vdin olandeză Proberen și Verhogen înseamnă „a testa” și „a crește”. Valoarea inițială a unui semafor este numărul de unități de resurse (exemplu: memorii, imprimante etc.); este decrementat de fiecare dată când un proces execută operațiunea P. Dacă este pozitiv, reprezintă deci numărul de resurse gratuite, altfel, dacă este negativ, valoarea sa absolută corespunde numărului de procese în așteptare.

Operațiile Pși Vtrebuie să fie atomice , ceea ce înseamnă că trebuie executate simultan și nu pot fi întrerupte între două „sub-operații”. Nu putem avea o situație în care două procese să testeze (aproape) simultan aceeași resursă și apoi să o rezerve (aproape) simultan. Primul proces trebuie să testeze și să rezerve resursa (sau să fie pus în așteptare) într-o singură operație și abia apoi poate fi testat și rezervat (sau să fie pus în așteptare).

În cărți în limba engleză, operațiunile Vși Psunt uneori denumite în sus și în jos, respectiv . În proiectarea software-ului, acestea sunt numite semnal și așteptați sau eliberați și luați . În mod informal, o modalitate bună de a vă aminti care face ceea ce este procesul mnemonic care îi asociază cu Puis-je? sau Ppredare și Vsă o ai! sau Vendre .

Pentru a evita așteptarea, un semafor poate avea o coadă de proces asociată (în general o coadă de tip FIFO ). Dacă un proces efectuează operația Ppe un semafor setat la zero, procesul se adaugă la coada de semafor. Când un alt proces crește semaforul în timp ce executați operația Vși există procese în coadă, unul dintre ele este eliminat din coadă și continuă executarea acestuia.

Init(sem, val)

Inițializarea unui semafor:

function Init(semaphore sem, int val){ disable_interrupt; sem.K = val; enable_interrupt; }

Standardul POSIX definește funcția sem_initpentru aceasta.

P(sem)

function P(semaphore sem){ disable_interrupt; if (sem.K <= 0){ L.suivant = processus_courant; processus_courant.état = bloque; reordonnancement = vrai; } sem.K = sem.K - 1; enable_interrupt; }

Standardul POSIX definește funcția sem_waitpentru aceasta.

V(sem)

function V(semaphore sem){ disable_interrupt; sem.K = sem.K+1; if (not L.vide){ processus_réveillé = L.tête; processus_réveillé.état = prêt; reordonnancement = vrai; } enable_interrupt; }

Standardul POSIX definește funcția sem_postpentru aceasta.

Incrementarea variabilei K nu trebuie întreruptă, iar operațiunea P nu trebuie întreruptă atunci când K este diferită de 0. Acest lucru se poate face printr-o instrucțiune specială sau prin ignorarea întreruperilor pentru a preveni procesul ulterior de a deveni activ. Semaforele pot fi utilizate pentru sincronizarea I / O.

utilizare

Semaforele sunt încă utilizate în limbaje de programare care nu implementează în mod inerent alte forme de sincronizare. Ele sunt mecanismul de sincronizare primitiv al multor sisteme de operare. Tendința în dezvoltarea limbajelor de programare este de a merge spre forme mai structurate de sincronizare precum monitoarele . În plus față de problemele de blocaj pe care le pot provoca, semaforele nu protejează programatorii de eroarea obișnuită a unui proces care blochează un semafor care este deja blocat de același proces și uită să lanseze un semafor care a fost blocat. Hoare , Hansen, Andrews, Wirth și chiar Dijkstra au considerat semaforul învechit .

Exemple

Blocarea semaforelor

În plus față de semaforele cu contor intern, există și semafoare blocante. Un semafor de blocare este un semafor care este inițializat cu valoarea 0. Aceasta are ca efect blocarea oricărui fir care face P (S) până când un alt fir are un V (S). Acest tip de utilizare este foarte util atunci când trebuie să controlați ordinea de execuție între fire . Această utilizare a semaforelor face posibilă crearea barierelor de sincronizare .

Excludere mutuala

Există, de asemenea, semaforul binar care este o excludere reciprocă (aka mutex). Este inițializat întotdeauna cu valoarea 1.

Cititori

O problemă clasică care poate fi rezolvată folosind semafoare este problema cititorului / scriitorului . Această ediție tratează accesul simultan de citire și scriere la o resursă. Mai multe procese ușoare ( fire ) pot citi resursa în același timp, dar nu poate exista decât un singur și un fir de scriere.

Producători-consumatori

Atunci când procesele ușoare doresc să comunice între ele, pot face acest lucru printr-o coadă . Trebuie să definiți comportamentul pe care trebuie să îl aveți atunci când un fir dorește să citească din coadă atunci când acesta din urmă este gol și când un fir dorește să scrie în coadă, dar acesta din urmă este plin.

Alte probleme

Deoarece semaforele sunt utilizate în special pentru sincronizare, ele pot duce la situații nedorite, de exemplu:

Note și referințe

  1. (în) Genuys, F. , Comitetul științific al NATO. și Universitatea din Grenoble. , Limbaje de programare; , Academic P,1968( ISBN  0-12-279750-7 și 978-0-12-279750-7 , OCLC  1068 , citit online ) , p.  43-112 (Cooperarea proceselor secvențiale de Dijkstra, EW)
  2. Informatică și tehnologie: STI., Volumul 5 , Dunod ( citiți online ).
  3. http://manpagesfr.free.fr/man/man3/sem_init.3.html .
  4. [1] [PDF] pagina 2.