Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so:cursuri:curs-08 [2015/05/06 08:48]
stefan_gabriel.mirea [Creare de thread-uri și spațiul de adresă]
so:cursuri:curs-08 [2019/04/10 23:07] (current)
razvan.deaconescu [Utilitate apeluri reentrante]
Line 1: Line 1:
 ====== Curs 08 - Fire de execuție ====== ====== Curs 08 - Fire de execuție ======
- 
-<​html>​ 
-<iframe src="​http://​prezi.com/​embed/​3noq9rp6p95k/?​bgcolor=ffffff&​amp;​lock_to_path=0&​amp;​autoplay=0&​amp;​autohide_ctrls=0&​amp;​features=undefined&​amp;​disabled_features=undefined"​ width="​550"​ height="​400"​ frameBorder="​0"></​iframe>​ 
-</​html>​ 
  
   * [[http://​prezi.com/​3noq9rp6p95k/​curs-8-so/?​kw=view-3noq9rp6p95k&​rc=ref-31844697 | Curs 08 - Fire de execuție (vizualizare Prezi)]]   * [[http://​prezi.com/​3noq9rp6p95k/​curs-8-so/?​kw=view-3noq9rp6p95k&​rc=ref-31844697 | Curs 08 - Fire de execuție (vizualizare Prezi)]]
   * [[http://​elf.cs.pub.ro/​so/​res/​cursuri/​SO_Curs-08.pdf | Curs 08 - Fire de execuție (PDF)]]   * [[http://​elf.cs.pub.ro/​so/​res/​cursuri/​SO_Curs-08.pdf | Curs 08 - Fire de execuție (PDF)]]
 +
 +  * [[https://​drive.google.com/​open?​id=1oXIYiGsEYUNviw2BJ27XFzJnIDcKg7H_MxcY0ifnMJA|Notițe de curs]]
  
   * Suport curs   * Suport curs
-    * Operating Systems Concepts+    * Operating Systems Concepts ​Essentials
       * Capitolul 4 - Threads       * Capitolul 4 - Threads
     * Modern Operating Systems     * Modern Operating Systems
Line 19: Line 17:
       * Capitolul 7 - Threads and Scheduling       * Capitolul 7 - Threads and Scheduling
       * Capitolul 8 - Thread Synchronization       * Capitolul 8 - Thread Synchronization
 +
 +<​html>​
 +  <​center>​
 +    <iframe src="​https://​prezi.com/​embed/​3noq9rp6p95k/?​bgcolor=ffffff&​amp;​lock_to_path=0&​amp;​autoplay=0&​amp;​autohide_ctrls=0&​amp;​features=undefined&​amp;​disabled_features=undefined"​ width="​550"​ height="​400"​ frameBorder="​0"></​iframe>​
 +  </​center>​
 +</​html>​
  
 ===== Demo-uri ===== ===== Demo-uri =====
Line 73: Line 77:
 ==== Partajare informație între procese și thread-uri ==== ==== Partajare informație între procese și thread-uri ====
  
-Ne propunem să investigăm modul în care thread-urile partajează datele, iar procesele nu. Pentru aceasta accesăm subdirectorul ''​creation-time/'';​ urmărim conținutul fișierelor ''​process.c''​ și ''​thread.c''​. În ambele fișiere se incrementează o variabilă globală (''​data_var''​) în cadrul unui proces nou și într-un thread nou. Variabila globală este inițializată la ''​0''​.+Ne propunem să investigăm modul în care thread-urile partajează datele, iar procesele nu. Pentru aceasta accesăm subdirectorul ''​shared-data/'';​ urmărim conținutul fișierelor ''​process.c''​ și ''​thread.c''​. În ambele fișiere se incrementează o variabilă globală (''​data_var''​) în cadrul unui proces nou și într-un thread nou. Variabila globală este inițializată la ''​0''​.
  
 Compilăm cele două programe folosind ''​make''​. Rezultă două fișiere în format executabil: process și thread. Compilăm cele două programe folosind ''​make''​. Rezultă două fișiere în format executabil: process și thread.
Line 86: Line 90:
 </​code>​ </​code>​
  
-Observăm că procesele au o secțiune de date proprie; fiecare incrementare s-a făcut de la ''​0''​ la ''​1''​. Thread-urile (aceluiași proces) partajează însă secțiunea de date. În acest caz un thread-ul nou creat incrementează variabila de la ''​0''​ la ''​1'',​ pe când thread-ul inițial incrementează variabila de la ''​1''​ la ''​2''​.+Observăm că procesele au o secțiune de date proprie; fiecare incrementare s-a făcut de la ''​0''​ la ''​1''​. Thread-urile (aceluiași proces) partajează însă secțiunea de date. În acest caz thread-ul nou creat incrementează variabila de la ''​0''​ la ''​1'',​ pe când thread-ul inițial incrementează variabila de la ''​1''​ la ''​2''​.
  
 ==== Stiva unui thread în spațiul de adresă ==== ==== Stiva unui thread în spațiul de adresă ====
  
-Ne propunem să urmărim ​seperația efectivă a stivelor thread-urilor aceluiași proces. Pentru aceasta accesăm subdirectorul ''​stack-access/'';​ urmărim conținutul fișierului ''​stack-access.c''​. În cadrul fișierului se creează două thread-uri ​una care citește și alta care scrie într-o variabilă.+Ne propunem să urmărim ​separația efectivă a stivelor thread-urilor aceluiași proces. Pentru aceasta accesăm subdirectorul ''​stack-access/'';​ urmărim conținutul fișierului ''​stack-access.c''​. În cadrul fișierului se creează două thread-uri, unul care citește și altul care scrie într-o variabilă.
  
 Programul este făcut în așa fel încât să se întâmple următoarea secvență: Programul este făcut în așa fel încât să se întâmple următoarea secvență:
Line 115: Line 119:
 </​code>​ </​code>​
  
-Observăm că, la final, thread-ul reader a afișat valoarea variabilei locale (de pe stiva sa) ''​local_var''​ iar valoarea acesteia este ''​0x22222222'',​ valoare stabilită de thread-ul writer. Thread-ul writer a reușit să scrie în stiva thread-ului reader. Acest lucru este posibil pentru că thread-urile partajează spațiul de adrese al procesului din care fac parte; deși fiecare thread are stiva sa, accesul unui thread la stiva altuia nu este protejat de sistemul de operare; ambele ​stivei ​se găsesc în același spațiu de adresă și orice thread le poate modifica pe oricare dintre ele.+Observăm că, la final, thread-ul reader a afișat valoarea variabilei locale (de pe stiva sa) ''​local_var''​ iar valoarea acesteia este ''​0x22222222'',​ valoare stabilită de thread-ul writer. Thread-ul writer a reușit să scrie în stiva thread-ului reader. Acest lucru este posibil pentru că thread-urile partajează spațiul de adrese al procesului din care fac parte; deși fiecare thread are stiva sa, accesul unui thread la stiva altuia nu este protejat de sistemul de operare; ambele ​stive se găsesc în același spațiu de adresă și orice thread le poate modifica pe oricare dintre ele.
 ==== Utilitate apeluri reentrante ==== ==== Utilitate apeluri reentrante ====
  
Line 135: Line 139:
 [...] 4992000 Apr  8 00:48 out-ok [...] 4992000 Apr  8 00:48 out-ok
 </​code>​ </​code>​
-Observăm că fișierul de ieșire în cazul executabilului cu varianta nereentrantă are dimensiunea mai mică, deci absența reentranței a cauzat incoerența datelor obținute.+Observăm că fișierul de ieșire în cazul executabilului cu varianta nereentrantă are dimensiunea mai mică, deci absența reentranței a cauzat incoerența datelor obținute. Acest lucru se întâmplă întrucât, în momentul în care un thread folosește funcția ''​printf''​ pentru a afișa bufferul ''​str_time[i]''​ un alt thread îl poate modifica chiar în acel moment, iar datele devin incoerente.
  
 Dacă folosim comanda ''​file''​ vom vedea că se raportează că fișierul ''​out''​ este conținut binar, încă o dovadă a incoerenței informațiilor furnizate:<​code bash> Dacă folosim comanda ''​file''​ vom vedea că se raportează că fișierul ''​out''​ este conținut binar, încă o dovadă a incoerenței informațiilor furnizate:<​code bash>
Line 145: Line 149:
  
 În cazul folosirii programelor cu thread-uri, trebuie folosite versiunile reentrante ale funcțiilor de bibliotecă. În cazul folosirii programelor cu thread-uri, trebuie folosite versiunile reentrante ale funcțiilor de bibliotecă.
 +
 +==== Implementare de thread-uri în Java și Python ====
 +
 +În Java și Python implementările de thread-uri sunt cu suport din partea sistemului de operare. Adică o operație de creare a unui thread rezultă în crearea unui thread în kernel space (kernel-level threads).
 +
 +Pentru a verifica acest lucru accesăm subdirectorul ''​lang/''​ unde avem fișierul sursă ''​MultithreadingTest.java''​ și ''​threading_demo.py''​. Pentru a compila fișierul ''​MultithreadingTest.java''​ folosim comanda ''​make''​.
 +
 +Rularea ambelor programe duce la crearea de a câte unui thread în momentul apăsării tastei ''​ENTER''​. Pentru Java rulăm comanda:
 +<​code>​
 +$ java MultithreadingTest
 +Press ENTER to create new thread ...
 +
 +Press ENTER to create new thread ...
 +Thread 12 is running
 +
 +Press ENTER to create new thread ...
 +Thread 13 is running
 +
 +Press ENTER to create new thread ...
 +Thread 14 is running
 +
 +Press ENTER to create new thread ...
 +Thread 15 is running
 +[...]
 +</​code>​
 +Durează ''​SLEEP_TIME''​ secunde ca thread-urile să își încheie execuția.
 +
 +Pentru Python rulăm:
 +<​code>​
 +$ python threading_demo.py
 +Press ENTER to create new thread ...
 +
 +Thread 140481023772416 is runningPress ENTER to create new thread ...
 +
 +
 +Thread 140481015379712 is running
 +Press ENTER to create new thread ...
 +
 +Press ENTER to create new thread ...
 + ​Thread 140481006987008 is running
 +
 +Thread 140480796948224 is running
 + Press ENTER to create new thread ...
 +[...]
 +</​code>​
 +La fel, durează ''​SLEEP_TIME''​ secunde ca thread-urile să își încheie execuția.
 +
 +Pentru a verifica faptul că sunt într-adevăr create thread-uri noi rulăm în altă terminal comenzile de mai jos pentru Java:
 +<​code>​
 +$ ps -efL | grep Multithreading | wc -l
 +35
 +$ ps -efL | grep Multithreading | wc -l
 +36
 +$ ps -efL | grep Multithreading | wc -l
 +37
 +$ ps -efL | grep Multithreading | wc -l
 +43
 +</​code>​
 +Observăm creșterea numărului de thread-uri pe măsură ce le creăm folosind opțiunea ''​-L''​ a comenzii ''​ps''​ (pentru //​lightweight process//).
 +
 +La fel procedăm și pentru Python:
 +<​code>​
 +$ ps -efL | grep threading_demo | wc -l
 +2
 +$ ps -efL | grep threading_demo | wc -l
 +4
 +$ ps -efL | grep threading_demo | wc -l
 +8
 +</​code>​
 +
 +De avut în vedere că în Python, deși thread-urile au suport în kernel și au potențialul de a rula simultan, nu vor face aceste lucru din cauza unui lock global din interpretorul Python numit GIL ([[https://​wiki.python.org/​moin/​GlobalInterpreterLock|Global Interpreter Lock]]). Este vorba de CPython, intepretorul de referință Python. IronPython nu are GIL și poate rula cu adevărat în paralel thread-uri cu suport de la nivelul nucleului.
so/cursuri/curs-08.1430891337.txt.gz · Last modified: 2015/05/06 08:48 by stefan_gabriel.mirea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0