This shows you the differences between two versions of the page.
so:cursuri:curs-09 [2015/05/13 15:51] stefan_gabriel.mirea [Nevoie de acces exclusiv] |
so:cursuri:curs-09 [2019/04/15 01:04] (current) razvan.deaconescu |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Curs 09 - Sincronizare ====== | ====== Curs 09 - Sincronizare ====== | ||
- | <html> | + | * [[http://elf.cs.pub.ro/so/res/cursuri/SO%20-%20Curs%2009%20-%20Sincronizare.pdf|Curs 09 - Sincronizare (PDF)]] |
- | <iframe src="http://docs.google.com/viewer?url=http://elf.cs.pub.ro/so/res/cursuri/SO_Curs-09.pdf&embedded=true" width="600" height="480" style="border: none;"> | + | |
- | </iframe> | + | |
- | </html> | + | |
- | * [[http://elf.cs.pub.ro/so/res/cursuri/SO_Curs-09.pdf | Curs 09 - Sincronizare (PDF)]] | + | * [[https://drive.google.com/open?id=1PCJp2UD0KSuAOFJ9ZMkB_lMhR9jJ4exD7Pgm-vzSrQA|Notițe de curs]] |
* Suport curs | * Suport curs | ||
- | * Operating Systems Concepts | + | * Operating Systems Concepts Essentials |
- | * Capitolul 5 - Process Synchronization | + | * Capitolul 6 - Process Synchronization |
* Modern Operating Systems | * Modern Operating Systems | ||
* Capitolul 2 - Processes and Threads | * Capitolul 2 - Processes and Threads | ||
* Secțiunea 2.3 - Interprocess Communication | * Secțiunea 2.3 - Interprocess Communication | ||
* [[http://greenteapress.com/semaphores/|Allen B. Downey - The Little Book of Semaphores]] | * [[http://greenteapress.com/semaphores/|Allen B. Downey - The Little Book of Semaphores]] | ||
+ | * [[https://deadlockempire.github.io/|The Deadlock Empire: Slay dragons, master concurency!]] | ||
+ | * [[http://elf.cs.pub.ro/so/res/cursuri/SO_Curs-09.pdf|Curs 09 anterior]] | ||
+ | |||
+ | |||
+ | <html> | ||
+ | <center> | ||
+ | <iframe src="https://docs.google.com/viewer?url=https://elf.cs.pub.ro/so/res/cursuri/SO%20-%20Curs%2009%20-%20Sincronizare.pdf&embedded=true" width="600" height="480" style="border: none;"> | ||
+ | </iframe> | ||
+ | </center> | ||
+ | </html> | ||
===== Demo-uri ===== | ===== Demo-uri ===== | ||
Line 58: | Line 65: | ||
Compilăm cele două programe folosind ''make''. Rezultă două fișiere în format executabil: ''spinlock'' și ''mutex''. | Compilăm cele două programe folosind ''make''. Rezultă două fișiere în format executabil: ''spinlock'' și ''mutex''. | ||
- | Cele două fișiere au fost generat din același cod sursă (''spinlock-mutex.c''), după cum a fost definit sau nu macro-ul ''USE_SPINLOCK''. Macro-ul îl definim în fișierul ''Makefile''. | + | Cele două fișiere au fost generate din același cod sursă (''spinlock-mutex.c''), după cum a fost definit sau nu macro-ul ''USE_SPINLOCK''. Macro-ul îl definim în fișierul ''Makefile''. |
Pentru a contabiliza timpul de rulare rulăm cele două executabile prin comanda ''time'':<code bash> | Pentru a contabiliza timpul de rulare rulăm cele două executabile prin comanda ''time'':<code bash> | ||
Line 92: | Line 99: | ||
adică o condiție de cursă de tipul TOCTTOU, în care se poate "infiltra" alt thread. Practic este posibil ca două thread-uri să scadă valoarea variabilei ''num_items'' deși condiția ar fi trebuit să se întâmple doar pentru unul. Dacă avem o valoare inițială ''NUM_ITEMS_CONSUMER + 2'', atunci există riscul ca mai multe thread-uri să vadă îndeplinită condiția și apoi toate să scadă valoarea variabilei ''num_items'' rezultând într-o valoare negativă. | adică o condiție de cursă de tipul TOCTTOU, în care se poate "infiltra" alt thread. Practic este posibil ca două thread-uri să scadă valoarea variabilei ''num_items'' deși condiția ar fi trebuit să se întâmple doar pentru unul. Dacă avem o valoare inițială ''NUM_ITEMS_CONSUMER + 2'', atunci există riscul ca mai multe thread-uri să vadă îndeplinită condiția și apoi toate să scadă valoarea variabilei ''num_items'' rezultând într-o valoare negativă. | ||
- | O astfel de situația poate duce la un comportament nedeterminst al programului, la coruperea datelor, chiar la încheierea cu eroare a programului. Mai mult o astfel de situație poate fi exploatată de un atacator. | + | O astfel de situație poate duce la un comportament nedeterminst al programului, la coruperea datelor, chiar la încheierea cu eroare a programului. Mai mult o astfel de situație poate fi exploatată de un atacator. |
Pentru a preveni apariția condițiilor de cursă, trebuie implementată corespunzător sincronizarea accesului. Din păcate, condițiile de cursă pot apărea foarte greu (adică programul să fie greșit dar să meargă **aproape** tot timpul); acest lucru face nedeterminist comportamentul programului și dificilă investigarea problemei. | Pentru a preveni apariția condițiilor de cursă, trebuie implementată corespunzător sincronizarea accesului. Din păcate, condițiile de cursă pot apărea foarte greu (adică programul să fie greșit dar să meargă **aproape** tot timpul); acest lucru face nedeterminist comportamentul programului și dificilă investigarea problemei. | ||
Line 159: | Line 166: | ||
În cele de mai sus, înainte de operația de unlock pe mutex am apelat funcția [[http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_signal.html|pthread_cond_signal]]. Cu ajutorul acestei funcții, thread-ul producător ce tocmai a produs un element trezește un thread consumator care acum are ce consuma; în mod similar thread-ul consumator care a consumat un element trezește un thread producător care acum are loc unde să producă un element. | În cele de mai sus, înainte de operația de unlock pe mutex am apelat funcția [[http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_signal.html|pthread_cond_signal]]. Cu ajutorul acestei funcții, thread-ul producător ce tocmai a produs un element trezește un thread consumator care acum are ce consuma; în mod similar thread-ul consumator care a consumat un element trezește un thread producător care acum are loc unde să producă un element. | ||
- | După actualizarea programulu, recompilăm folosind ''make'' și apoi îl rulăm. Acum programul va funcționa corespunzător fără problema așteptării nedefinite. | + | După actualizarea programului, recompilăm folosind ''make'' și apoi îl rulăm. Acum programul va funcționa corespunzător fără problema așteptării nedefinite. |
==== Granularitate regiune critică ==== | ==== Granularitate regiune critică ==== | ||
Line 173: | Line 180: | ||
</code> | </code> | ||
- | Observăm că dureaza semnificativ mai mult rularea executabilului cu granularitate fină. Acest lucru se întâmplă pentru că regiunea critică pe care acesta o protejează este mic, iar cea mai mare parte din timp o va consuma în operațiile cu mutex-ul (//lock contention//). Observăm acest lucru și din numărul mare de schimbări de context (voluntare sau nevoluntare). | + | Observăm că dureaza semnificativ mai mult rularea executabilului cu granularitate fină. Acest lucru se întâmplă pentru că regiunea critică pe care acesta o protejează este mică, iar cea mai mare parte din timp o va consuma în operațiile cu mutex-ul (//lock contention//). Observăm acest lucru și din numărul mare de schimbări de context (voluntare sau nevoluntare). |
<note> | <note> | ||
În general preferăm granularitate fină pentru regiunile critice (adică regiuni critice de mică dimensiune); dar granularitatea fină poate înseamna operații foarte dese pe mutex (//lock contention//). De aceea este recomandat ca folosirea granularității fine să fie echilibrată de un număr redus de thread-uri care să dorească să acceseze la un moment dat regiunea critică, pentru a genera cât mai puțină încărcare (//contention//) pe mutex. | În general preferăm granularitate fină pentru regiunile critice (adică regiuni critice de mică dimensiune); dar granularitatea fină poate înseamna operații foarte dese pe mutex (//lock contention//). De aceea este recomandat ca folosirea granularității fine să fie echilibrată de un număr redus de thread-uri care să dorească să acceseze la un moment dat regiunea critică, pentru a genera cât mai puțină încărcare (//contention//) pe mutex. | ||
</note> | </note> | ||
- |