c3#vniculescu/didactic/pp/... · 2020. 10. 22. · c3# procese,#thread/uri, taskuri# concurenta#...
TRANSCRIPT
-
C3
Procese, Thread-‐uri, Taskuri Concurenta Java Threads
Pradigme si Tehnici ale programarii paralele 1
-
Concurenta
• Concurrency: – Mul?processing – Mul?tasking – Any combina?on of them
• Probleme -‐> termeni – race condi?ons, deadlock, starva?on,…
Pradigme si Tehnici ale programarii paralele 2
-
Mul?processing -‐> Paralelism
• Mul?core processors
• Se folosesc mai multe unita? de procesare • Procesele se executa in acelasi ?mp
Pradigme si Tehnici ale programarii paralele 3
-
Mul?tasking-‐> Concurenta
• Sistemul de operare schimba execu?a intre diferite taskuri
• Interleaving – sunt mai multe taskuri ac?ve, dar doar unul se executa la un moment dat
• Mul?tasking: – SO ruleaza execu?i intretesute
Pradigme si Tehnici ale programarii paralele 4
-
Procese
• Un program (secven?al) = un set de instruc?uni – (in pradigma programarii impera?ve)
• Un proces = o instanta a unui program care se executa
Pradigme si Tehnici ale programarii paralele 5
-
Procese in sisteme de operare
• Structura unui proces – Iden?ficator de proces (ID) – Starea procesului (ac?vitatea curenta) – Contextul procesului (valori registrii, program counter) – Memorie (codul program, date globale, s?va si heap)
Pradigme si Tehnici ale programarii paralele 6
-
Scheduler
• Un program care controleaza execu?a proceselor – Seteaza starile procesului
• new • running • blocked (nu poate fi selectat pt execu?e; este nevoie de un event extern pt a iesi din aceasta stare) • ready • terminated
Pradigme si Tehnici ale programarii paralele 7
-
Pradigme si Tehnici ale programarii paralele 8
-
Context switch
• Atunci cand OS scheduler schimba procesul executat de o unitate de procesare
• Ac?uni asociate: – P1.state := ready – Se salveaza valoarea registrilor in memorie ca si context al lui P1 – Se foloseste contextul lui P2 pt a seta registrii – P2.state := running
Pradigme si Tehnici ale programarii paralele 9
-
Threads
• Un thread este o parte a unui proces al sistemului de operare • Componente private fiecarui thread:
– Iden?ficator – Stare – Context – Memorie (doar s?va)
• Componente partajate cu alte thread-‐uri – Cod program – Date globale – Heap
Pradigme si Tehnici ale programarii paralele 10
-
Concurenta cu Threads
Program concurent: un program care la execu?e conduce la un proces care con?ne mai multe threaduri
Pradigme si Tehnici ale programarii paralele 11
-
Variante de execu?e
• Secvente de execu?e
Pradigme si Tehnici ale programarii paralele 12
-
Race condi?on & Cri?cal sec?on
• Procese / threaduri independente => execu?e simpla fara probleme
• Daca exista interac?une (ex. Accesarea si modificarea acelasi variabile) => pot apare probleme
• Nondeterminis+c interleaving
• Daca rezultatul depinde de interleaving => race condi7on (data race)
• Pot fi erori extrem de greu de depistat!!!
• O sec?une de cod care conduce la o condi?e de ?p race condi+on este numita sec$une cri$ca (cri7cal sec7on)
Pradigme si Tehnici ale programarii paralele 13
-
Instruc?uni atomice
• este atomica daca execu?a sa nu poate fi “interleaved” cu cea a altei instruc?uni inainte de terminarea ei.
• Niveluri de atomicitate
Ex: x:= x + 1 Execu?e:
temp := x LOAD REG, x
temp := temp + 1 ADD REG, #1
x := temp STORE REG, x
Pradigme si Tehnici ale programarii paralele 14
-
Variante de execu?e
• exemplul anterior
• o execu?e "interleaving"
Pradigme si Tehnici ale programarii paralele 15
-
Thread Safety vs Shared Resources
• Un cod pentru care este sigur apelul simultan de catre mai multe thread-‐uri – indiferent de posibila execu?e intretesuta -‐ se numeste cod thread safe.
• Daca un cod este thread safe, atunci sigur nu con?ne race condi+ons.
• O condi?e de ?p race condi7on apare doar atunci cand mai multe threaduri actualizeaza o resursa comuna.
Pradigme si Tehnici ale programarii paralele 16
-
Threads
Java
Pradigme si Tehnici ale programarii paralele 17
-
Java threads
Pradigme si Tehnici ale programarii paralele 18
public class HelloRunnable implements Runnable {
public void run() { System.out.println("Hello from a
thread!"); } public sta?c void main (String args[]) {
(new Thread (new HelloRunnable())).start(); …….. }
}
public class HelloThread extends Thread { public void run() {
System.out.println("Hello from a thread!"); } public sta?c void main(String args[]) {
(new HelloThread()).start(); ……….. }
}
-
Main Thread
• When a Java Virtual Machine starts up, there is usually a single non-‐daemon thread (which typically calls the method named main of some designated class).
• The Java Virtual Machine con?nues to execute threads un?l either of the following occurs:
– The exit method of class Run?me has been called and the security manager has permioed the exit opera?on to take place.
– All threads that are not daemon threads have died, either by returning from
the call to the run method or by throwing an excep?on that propagates beyond the run method.
Pradigme si Tehnici ale programarii paralele 19
-
Java Thread State (public Thread.State getState())
public sta$c enum Thread.State extends Enum A thread state. A thread can be in one of the following states: NEW A thread that has not yet started is in this state. RUNNABLE A thread execu?ng in the Java virtual machine is in this state. BLOCKED A thread that is blocked wai?ng for a monitor lock is in this state. WAITING A thread that is wai?ng indefinitely for another thread to perform a par?cular ac?on is in this state. TIMED_WAITING A thread that is wai?ng for another thread to perform an ac?on for up to a specified wai?ng ?me is in this state. TERMINATED A thread that has exited is in this state.
Pradigme si Tehnici ale programarii paralele 20
-
21
Thread control
• join() wait for thread to finish
• sleep(int n) sleep for n ms (keep locks) • interrupt() send signal to interrupt a sleeping or wai?ng thread • yield() suggest another can run
Pradigme si Tehnici ale programarii paralele
-
22
Race Condi7ons & Cri7cal Sec7ons
• Situa?a in care 2 sau mai multe threaduri se "lupta” pentru o resursa comuna (ex. variabila) este de ?p race condi+on.
• O sec?une de cod care conduce la o condi?e de ?p race condi+on este numita sec$une cri$ca (cri7cal sec7on).
public class Counter { protected long count = 0; public void add(long value){ this.count = this.count + value; } }
Pradigme si Tehnici ale programarii paralele
-
23
Variabile locale
• Variabilele locale din thread-‐uri sunt stocate pe s+va fiecarui thread. • Nu sunt partajate. • Prin urmare toate variabilele primi?ve locale sunt thread safe.
Ex: public void someMethod(){ long threadSafeInt = 0; threadSafeInt++; }
Pradigme si Tehnici ale programarii paralele
-
24
Referinte Locale
• Referintele nu sunt partajate (orice obiect este accesibil printr-‐o referinta). • Obiectul referit este partajat (shared heap). • Daca un obiect creat local nu se foloseste decat local in metoda care il creeaza
atunci este thread safe. • Daca un obiect creat local este transferat altor metode dar nu este transferat altor
threaduri atunci este thread safe.
Ex: public void someMethod(){ LocalObject localObject = new LocalObject(); localObject.callMethod(); method2(localObject); } public void method2(LocalObject localObject){ localObject.setValue("value"); }
Pradigme si Tehnici ale programarii paralele
-
25
Exemplu: not thread safe
public class NotThreadSafe{ StringBuilder builder = new StringBuilder(); public add(String text){ this.builder.append(text); } } /////////////////////////////////////////////////// public class MyRunnable implements Runnable{ NotThreadSafe instance = null; public MyRunnable(NotThreadSafe instance){ this.instance = instance; } public void run(){ this.instance.add("some text"); } }
NotThreadSafe sharedInstance = new NotThreadSafe();
new Thread(new
MyRunnable(sharedInstance)).start(); new Thread(new
MyRunnable(sharedInstance)).start();
Pradigme si Tehnici ale programarii paralele
-
26
Shared Variables
• shared memory (heap memory).
• Toate atributele claselor , campurile sta?ce si elementele tablourilor sunt stocate in heap è shared.
• Doua opera?i de acces (read or write) la aceeasi variabila se spune ca sunt in conflict daca cel pu?n unul este scriere (write).
Pradigme si Tehnici ale programarii paralele
-
Thread-‐Safe shared variables
• Daca mai multe thread-‐uri folosesc o variabila mutabila(modificabila) fara sa foloseasca sincronizari codul nu este safe.
• Solu?i:
– eliminarea partajarii valorii variabilei intre threaduri – transformarea variabile in variabila–imutabila (var imutabile sunt thread-‐safe) – sincronizarea accesului la starea variabilei
Pradigme si Tehnici ale programarii paralele 27
-
Thread-‐safe classes
• Thread-‐safe class
– daca comportamentul instantelor sale este corect chiar daca este accesat din threaduri mul?ple indiferent de execu?a intretesuta a lor(interleaving) fara sa fie nevoie de sincronizari adi?onale sau alte condi?i impose codului apelant.
– sincronizarile sunt incapsulate in interior si asvel clien?i clasei nu trebuie sa
foloseasca altele speciale.
Pradigme si Tehnici ale programarii paralele 28
-
29
Variabile locale / globale
• instance fields, | • static fields, and | • array elements | => heap memory.
Ø local variables, | Ø method parameters, and | Ø exception handler parameters |=> local for each thread (stack)
-
30
Synchronization
• monitors • Lock or unlock.
• synchronized statement • synchronized methods
-
31
fine-grained synchronization
public class Counter { private long c1 = 0; private long c2 = 0; private Object lock1 = new Object(); private Object lock2 = new Object(); public void inc1() { synchronized(lock1) { c1++; } } public void inc2() { synchronized(lock2) { c2++; } } }
• Ce se intampla daca lock1 sau lock2 se modifica?
-
32
Exemplu
public class SynchronizedCounter { private int c = 0; public synchronized void increment() { c++; } public synchronized void decrement() { c--; } public synchronized int value() { return c; } }
-
33
Variabile volatile
• – valoarea variabile nu va fi niciodata salvata local (cached thread-
locally) – toate citirile scrierile => "main memory"; – efect similar synchronized block. – nu se executa nici o blocare mutual exclusiva.
-
34
Wait si Notify
• Fiecare obiect are pe langa un monitor asociat si o multime - wait set. – multime de thread-uri.
• atunci cand un obiect se creeaza aceasta multime e vida. Modificari se produc in urma apelurilor metodelor: – Object.wait – Object.notify – Object.notifyAll
• Wait set poate fi afectata de "interruption status" a unui thread si de catre metodele care opereaza intreruperi.
• In plus, metodele sleep si join ale altor threaduri au proprietati derivate din
acelea ale actiunilor de asteptare si notificare.
-
35
Wait
• – wait(), – wait(long millisecs) – wait(long millisecs, int nanosecs).
• Un thread "returns normally" dintr-o asteptare daca nu arunca o expectie de tip InterruptedException.
-
36
Mecanism detaliat
• Fie threadul t care executa o metoda wait pe obiectul o, – fie n = numarul de actiuni de blocare ale lui t pe o pt care nu au existat
operatii pereche de deblocare. Atunci:
– Daca n =0, atunci se arunca IllegalMonitorStateException. Acesta este cazul in care t nu poseda inca blocarea pe o.
– Daca wait este de tip timed wait si argumentul nu este in intervalul
0-999999 sau este negativ, atunci se arunca llegalArgumentException. – Daca t este interrupted, atunci se arunca InterruptedException si
interruption status pentru t este setat la false.
-
37
Altfel exista urm. situatii 1. Thread-ul t este adaugat multimii wait set pentru obiectul o si executa n
deblocari pe o. Atunci:
Thread-ul t nu executa alte instructiuni pana cand nu este sters din wait set al lui o. Thread-ul t poate fi sters din wait set al lui o ca urmare a uneia din urm. actiuni (si apoi isi va relua executia) :
◆ O actiune notify asupra lui o in care t este selectat spre a fi sters din wait set. ◆ O actiune notifyAll asupra lui o . ◆ O actiune de intrerupere realizata de t. ◆ Trecerea timpului (argument) specificat la apelul lui wait. ◆ Operatii "spurious wake-ups" – nerecomandate/rare.
-
38
Conditii
• folosirea operatiilor wait doar in cicluri care se termina atunci cand anumite conditii logice sunt indeplinite.
• fiecare thread trebuie sa determine o ordine intre evenimentele care pot cauza ca el sa fie sters din wait set.
De exemplu: daca t este in wait set pt o, atunci cand apare atat o intrerupere
a lui t cat si o notificare a lui o, trebuie sa existe o ordine intre aceste evenimente.
÷ Daca interrupt este considerata prima, atunci pana la urma t iese din wait aruncand InterruptedException, si alt thread din wait set a lui o (daca mai exista vreunul) va primi notificarea.
÷ Daca sunt invers ordonate atunci t iese normal din wait si intreruperea este in asteptare (pana se verifica starea).
-
39
2. Thread-ul t executa n operatii de deblocare pe o. 3. Daca thread t a fost sters din wait set a lui o din cauza unei intreruperi atunci
interruption status al lui t este setat la false si se iese din wait cu aruncarea unei exceptii de tip InterruptedException.
-
40
Notification
• no$fy • no$fyAll
• Fie threadul t executa una dintre cele 2 metode pe obiectul o, • fie n = numarul de opera7i de blocare a lui t care nu s-‐au potrivit cu ac7uni de deblocare. Una dintre urm. ac?uni apare:
– Daca n =0, atunci se arunca o excep?e IllegalMonitorStateExcep?on. Acesta este cazul in care t nu poseda nici un lock pe o. – Daca n>0 si este o ac?une no$fy si wait set a lui o nu e vida atunci un thread u care
este inclus in wait set a lui o este selectat si sters din acea mul?me. Aceasta stergere permite resuscitarea lui u din ac?unea de asteptare. Totusi ac?unile lui u nu pot reusi mai devreme ca t sa deblocheze complet monitorul lui o.
(Nu exista nici o garan?e ca un anumit thread sau altul va fi ales.) – Daca n>0 si este o ac?une no$fyAll atunci toate threadurile sunt sterse din wait set a
lui m.
• Totusi doar unul va debloca monitorul atunci cand va iesi din wait.
-
41
Interruptions
• Actiunile Interruption actions occur upon invocation of Thread.interrupt, as well as methods defined to invoke it in turn, such as ThreadGroup.interrupt.
• Let t be the thread invoking u.interrupt, for some thread u, where t and u may be the same. This action causes u's interruption status to be set to true.
• Additionally, if there exists some object o whose wait set contains u, then u is removed from m's wait set. This enables u to resume in a wait action, in which case this wait will, after re-locking m's monitor, throw InterruptedException.
• Invocations of Thread.isInterrupted can determine a thread's interruption status. The static method Thread.interrupted may be invoked by a thread to observe and clear its own interruption status.
-
42
Intreruperi
• mecanismul de intrerupere foloseste un flag intern -> the interrupt status.
• Atunci cand se apeleaza Thread.interrupt se seteaza acest flag.
• Atunci cand se verifica intreruperea prin metoda statica Thread.interrupted, este sters.
• Metoda nestatica isInterrupted, care este folosita de catre un thread pt a verifica statusul (interrupt status) al altuia nu schimba flagul.
• Prin conventie, orice metoda care se termina (exit) aruncand o exceptie de tip InterruptedException sterge "interrupt status".
• Totusi este posibil ca acesta sa fie imediat setat din nou de catre alt thread care invoca o metoda interrupt.
-
43
Exemplu public class SimpleThreads { static void threadMessage(String message) { String threadName = Thread.currentThread().getName(); System.out.format("%s: %s %n", threadName, message); } private static class MessageLoop implements Runnable { public void run() { String importantInfo[] = { "Mares eat oats", "Does eat oats", "Little lambs eat ivy", "A kid will eat ivy too" }; try { for (int i = 0; i < importantInfo.length; i++) { // Pause for 4 seconds Thread.sleep(4000); // Print a message threadMessage(importantInfo[i]); } } catch (InterruptedException e) { threadMessage("I wasn't done!"); } } }
-
44
public static void main(String args[]) throws InterruptedException { // Delay, in milliseconds before // we interrupt MessageLoop // thread (default one hour). long patience = 1000 * 60 * 60; // If command line argument present,
// gives patience in seconds. if (args.length > 0) { try { patience = Long.parseLong(args[0]) * 1000; }
catch (NumberFormatException e) { System.err.println("Argument must be an
integer."); System.exit(1);
} }
threadMessage("Starting MessageLoop thread"); long startTime = System.currentTimeMillis(); Thread t = new Thread(new MessageLoop()); t.start(); threadMessage("Waiting for MessageLoop thread to
finish"); while (t.isAlive()) { threadMessage("Still waiting...");
t.join(1000); if (((System.currentTimeMillis() - startTime) >
patience) && t.isAlive()) { threadMessage("Tired of waiting!"); t.interrupt(); // Shouldn't be long now // -- wait indefinitely t.join(); } } threadMessage("Finally!"); } }
-
45
Interactiuni intre Waits, Notification, si Interruption
• Notificarile nu se pot perde din cauza intreruperilor.
• Presupunem ca un set de threaduri s este in wait set a lui o, si alt thread executa notificare pe o.
Atunci fie: – cel putin un thread din s iese normal din wait, sau – toate threadurile din s ies din wait aruncand exceptie InterruptedException
• Daca un thread este atat intrerupt cat si trezit prin notificare si el iese din wait aruncand o exceptie si atunci un alt thread din wait set va fi notificat.
-
46
Exemplu public class Producer extends Thread { private CubbyHole cubbyhole;
// shared data private int number; public Producer(CubbyHole c, int number)
{ cubbyhole = c; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { cubbyhole.put(i);
// Accesses shared data System.out.println("Producer #" +
this.number + " put: " + i); try { sleep((int)(Math.random() * 100)); } catch (InterruptedException e) { } } } }
public class Consumer extends Thread { private CubbyHole cubbyhole;
// shared data private int number; public Consumer(CubbyHole c, int
number) { cubbyhole = c; this.number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { value = cubbyhole.get();
// Accesses shared data System.out.println("Consumer #" +
this.number + " got: " + value); } } }
-
47
public class CubbyHole { private int contents; // shared data private boolean available = false; /* Method used by the consumer to access the shared data */ public synchronized int get() { while (available == false) { try { wait(); // Consumer enters a wait state until notified by the Producer } catch (InterruptedException e) { } } available = false; notifyAll(); // Consumer notifies Producer that it can store new contents return contents; } /* Method used by the producer to stor the shared data */ public synchronized void put (int value) { while (available == true) { try { wait(); // Producer who wants to store contents enters
// a wait state until notified by the Consumer } catch (InterruptedException e) { } } contents = value; available = true; notifyAll(); // Producer notifies Consumer to come out
// of the wait state and consume the contents } }
-
48
exemplu: BlockingQueue
/** Extend Queue to make threads block until remove has * data. */ class BlockingQueue { int n = 0; Queue data = ...; public synchronized Object remove() { // wait until there is something to read while (n==0) this.wait(); // we have the lock and state we're seeking n--; // return data element from queue } public synchronized void write(Object o) { n++; // add data to queue // have data. tell any waiting threads to wake up notifyAll(); } }
-
49
Java vola?le keyword
• vola?le – indica faptul ca o variabila va fi modificata de mai multe thread-‐uri.
• Efect: – Valoarea variabilei nu va fi cached thread-‐locally: toate ci?rile si scrierile se
vor face direct in "main memory"(heap); – Accesul la variabila este ca si cum ar fi inclus intr-‐o sec?une sincronizata
(monitor al variabilei insasi) . – se garanteaza accesul sincronizat – volatile nu va face nici o blocare mutual recursiva asupra variabilei.
Pradigme si Tehnici ale programarii paralele
-
50
Vola?le
• se garanteaza ca orice thread va ci? ul?ma valoare a campului v (cea mai recenta modificare a sa).
• Din versiunea Java 5 sunt vizibile si toate efectele colaterale (side effects).
è accesul (write) la o variabila vola?la va actualiza si variabilele non-‐vola?le care au fost modificate de acelasi thread.
class Vola$leExample { int x = 0; vola$le boolean v = false; public void writer() { x = 42; v = true; } public void reader() { if (v == true) { //uses x -‐ guaranteed to see 42. } } }
Pradigme si Tehnici ale programarii paralele
-
51
Exemplu
public class Singleton{ private static volatile Singleton _instance; //volatile variable public static Singleton getInstance(){ if(_instance == null){
synchronized(Singleton.class){
if(_instance == null) _instance = new Singleton();
} } return _instance; }
Fara vola?le atunci thread A nu s?e ca thread B ar putea accesa variabila. Asvel thread A considera ok sa foloseasca o copie (cache the value) intr-‐un registru sau in memoria locala è probleme
Pradigme si Tehnici ale programarii paralele
-
52
public class StoppableTask extends Thread { private vola$le boolean pleaseStop; public void run() { while (!pleaseStop) { // do some stuff... } } public void tellMeToStop() { pleaseStop = true; } }
Fara vola?le: -‐ threadul care executa ciclul poate sa copieze (cache) the variabila pleaseStop la
inceputul ciclului si sa nu o mai citeasca din nou.
Exemplu
Pradigme si Tehnici ale programarii paralele
-
53
Atomic Access
• atomic ac?on – se executa fie complet fie deloc – pana cand nu se termina nu sunt vizibile nici un fel de side effects (modificari).
• in general o simpla incrementare nu este o ac?une atomica. Se pot insa specifica ac?uni atomice :
– Reads /writes pt variabile referinta si pentru var primi?ve cu excep?a celor de ?p long si double.
– Reads / writes a pt toate variabilele declarate vola$le (inclusiv cele de 7p long si double)
• Folosirea variabilelor vola?le reduce riscul de a se ajunge la erori de consistenta a memoriei (dar nu le exclud).
• Modificarea unei variabile vola?le este vizibila celorlalte threaduri.
Pradigme si Tehnici ale programarii paralele
-
54
Diferente intre synchronized si vola?le
– o variabila primi?va poate fi declarata vola?le – nu se poate folosi synchronized pe o variabila primi?va;
– accesul la o variabila vola?le nu are poten?al de blocare (niciodata);
– pentru ca accesul la o var vola?le nu implica o blocare nu este potrivit pentru cazurile in care dorim ac?uni de ?p read-‐update-‐write sa fie tratate ca si opera?i atomice;
– o var vola?le care este referinta la un obiect poate fi nula (se asigura accesul atomic la referinta nu la obiectul);
– incercarea de a sincroniza un obiect null è throw NullPointerExcep?on.
Pradigme si Tehnici ale programarii paralele
-
Sincronizare
• Pentru a se rezolva problemele legate de "race condi?ons" execu?a procesele se sincronizeaza.
• Sincronizarea implica faptul ca procesele agreeaza impreuna o secventa de ac?uni.
• Exemple: – doar un proces poate sa foloseasca o resursa la un moment dat (exclusive use) – un proces se executa doar daca altul s-‐a executat anterior
Pradigme si Tehnici ale programarii paralele 55
-
Comunicare intre procese
• Shared memory – se scriu si se citesc date in sec?unile partajate ale memoriei
(Pentru thread-‐uri doar acest ?p de comunicare se aplica.)
• Distributed memory – transmitere de mesaje (send, receive, ...)
Pradigme si Tehnici ale programarii paralele 56
-
Safety -‐ Liveness
• Safety – "nothing bad ever happens"
• Liveness – "something good eventually happens"
Pradigme si Tehnici ale programarii paralele 57
-
Deadlock – Starva?on -‐-‐ Fairness
• Deadlock – situa?a in care un grup de procese se blocheaza la infinit pentru ca fiecarea proces
asteapta dupa o resursa care este re?nuta de alt proces care la randul lui asteapta dupa alta resursa.
• Starva+on – situa?a in care accesul este mereu refuzat
• Fairness – presupune o rezolvare corecta a nedeterminismului in execu?e – Weak fairness
• daca o ac?une este in mod con?nuu accesibila(con7nuously enabled)(stare-‐ready) atunci trebuie sa fie executata infinit de des (infinetely oIen).
– Strong fairness • daca o ac?une este infinit de des accesibilila (unfinetely oIen enabled) dar nu
obligatoriu in mod con?nuu atunci trebuie sa fie executata infinit de des (infinetely oIen).
Pradigme si Tehnici ale programarii paralele 58
-
Semafoare: avantaje -‐ dezavantaje
Semafoarele – primi?va de sincronizare -‐ conceptual – simpla, eficienta si versa?la
Se poate considera ca semafoarele furnizeaza "prea multa" flexibilitate:
– Nu se poate determina u?lizarea corecta a semafoarelor doar din bucata de cod unde ele apar;-‐ e posibil ca intreg codul sa fie nevoie a fi evaluat
– daca se uita sau se pozi?oneaza incorect o opera?e (V sau P) se compromite corec?tudinea;
– e usor sa se ajunga la deadlock atunci cand se folosesc (dificil de depanat).
Pradigme si Tehnici ale programarii paralele 59