Differences

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

Link to this comparison view

so:curs:sync [2020/04/26 19:43]
razvan.deaconescu
so:curs:sync [2020/05/04 10:56] (current)
alexandru.radovici
Line 11: Line 11:
     * [[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!]]     * [[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]] 
  
   * Filmări   * Filmări
 +    * 3CA https://​web.microsoftstream.com/​video/​75a1f57d-0d45-4188-96ca-43e62f6f6b42
     * 3CC curs 13, partea 1: https://​web.microsoftstream.com/​video/​7457610e-0320-4434-accf-cd449fdd4e75     * 3CC curs 13, partea 1: https://​web.microsoftstream.com/​video/​7457610e-0320-4434-accf-cd449fdd4e75
     * 3CC curs 13, partea a 2-a: https://​web.microsoftstream.com/​video/​862388ca-ad3b-4519-a344-8a7cce246103     * 3CC curs 13, partea a 2-a: https://​web.microsoftstream.com/​video/​862388ca-ad3b-4519-a344-8a7cce246103
 +    * 3CC curs 14, partea 1: https://​web.microsoftstream.com/​video/​97632417-905b-4021-a458-5277cd771d81
 +    * 3CC curs 14, partea a 2-a: https://​web.microsoftstream.com/​video/​fb26404e-495d-4c9e-ab6b-ef28715f0486
  
   * Resurse vechi   * Resurse vechi
     * [[http://​elf.cs.pub.ro/​so/​res/​cursuri/​SO%20-%20Curs%2009%20-%20Sincronizare.pdf|Curs 09 - Sincronizare (PDF)]]     * [[http://​elf.cs.pub.ro/​so/​res/​cursuri/​SO%20-%20Curs%2009%20-%20Sincronizare.pdf|Curs 09 - Sincronizare (PDF)]]
 +    * [[http://​elf.cs.pub.ro/​so/​res/​cursuri/​SO_Curs-09.pdf|Curs 09 anterior]]
 +
 +  * Curs CA [[https://​www.slideshare.net/​alexandruradovici/​sisteme-de-operare-sincronizare|slideshare]]
  
 ===== Demo-uri ===== ===== Demo-uri =====
Line 40: Line 45:
 Programul ''​thread-list-app-mutex''​ folosește intern un mutex pentru sincronizare. Pentru aceasta folosim macro-ul ''​USE_MUTEX''​ pe care îl definim în fișierul ''​Makefile''​. Programul ''​thread-list-app-mutex''​ folosește intern un mutex pentru sincronizare. Pentru aceasta folosim macro-ul ''​USE_MUTEX''​ pe care îl definim în fișierul ''​Makefile''​.
  
-Ca să urmărim ce se întâmplă cu o aplicație multithreaded cu date partajate, rulăm de mai multe ori programul ''​thread-list-app'',​ până la obținerea unei erori:<​code bash> +Ca să urmărim ce se întâmplă cu o aplicație multithreaded cu date partajate, rulăm de mai multe ori programul ''​thread-list-app'',​ până la obținerea unei erori: 
-./​thread-list-app+<code bash> 
 +for i in $(seq 1 20); do ./​thread-list-app; done
 </​code>​ </​code>​
  
Line 50: Line 56:
 Eroarea este cauzată de coruperea pointerilor din lista înlănțuită a programului. Datele sunt accesate concurent, iar în absența sincronizării,​ vor fi corupte. Eroarea este cauzată de coruperea pointerilor din lista înlănțuită a programului. Datele sunt accesate concurent, iar în absența sincronizării,​ vor fi corupte.
  
-Soluția este să folosim un mutex pentru protejarea accesului la listă, lucru realizat în programul ''​thread-list-app-mutex''​. Dacă vom rula de mai multe ori programul ''​thread-list-app-mutex'',​ nu vom obține niciodată eroare:<​code bash> +Soluția este să folosim un mutex pentru protejarea accesului la listă, lucru realizat în programul ''​thread-list-app-mutex''​. Dacă vom rula de mai multe ori programul ''​thread-list-app-mutex'',​ nu vom obține niciodată eroare: 
-./​thread-list-app-mutex+<code bash> 
 +for i in $(seq 1 20); do ./​thread-list-app-mutex; done
 </​code>​ </​code>​
  
Line 109: Line 116:
  
 Pentru a demonstra operațiile atomice și neatomice pe accesăm subdirectorul ''​sum-threads/''​ (x86) sau subdirectorul ''​sum-threads-arm''​ (ARM); urmărim fișierul ''​sum_threads.c'',​ identic în ambele subdirectoare. În fișier sunt create ''​NUM_THREADS''​ thread-uri care în ''​NUM_ROUNDS''​ runde efectuază operația ''​sum += v'',​ cu ajutorul macro-ului ''​do_op()''​. Folosim suportul compilatorului GCC și realizăm atomizarea operației ''​sum += v''​ cu ajutorul construcției ''​%%__sync_fetch_and_add()%%''​. Atunci când definim macro-ul ''​USE_ATOMIC''​ realizăm operația în mod atomic. Pentru a demonstra operațiile atomice și neatomice pe accesăm subdirectorul ''​sum-threads/''​ (x86) sau subdirectorul ''​sum-threads-arm''​ (ARM); urmărim fișierul ''​sum_threads.c'',​ identic în ambele subdirectoare. În fișier sunt create ''​NUM_THREADS''​ thread-uri care în ''​NUM_ROUNDS''​ runde efectuază operația ''​sum += v'',​ cu ajutorul macro-ului ''​do_op()''​. Folosim suportul compilatorului GCC și realizăm atomizarea operației ''​sum += v''​ cu ajutorul construcției ''​%%__sync_fetch_and_add()%%''​. Atunci când definim macro-ul ''​USE_ATOMIC''​ realizăm operația în mod atomic.
 +
 +<note important>​
 +Pentru folosirea ''​perf''​ va trebui să instalați pachetul corespunzător versiunii de nucleu. Pe o distribuție Debian/​Ubuntu,​ folosiți comanda:
 +<​code>​
 +sudo apt install linux-tools-$(uname -r)
 +</​code>​
 +</​note>​
  
 === x86 === === x86 ===
Line 593: Line 607:
  
 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>
-/​usr/​bin/​time ./​spinlock +/​usr/​bin/​time ​-v ./​spinlock 
-/​usr/​bin/​time ./mutex+/​usr/​bin/​time ​-v ./mutex
 </​code>​ </​code>​
  
Line 670: Line 684:
 ==== Buffer circular ==== ==== Buffer circular ====
  
-TODO+În multe dintre cazurile în care există entități de tipul producător și entități de tipul consumator, structura folosită este un buffer circular (//ring buffer//). Într-un astfel de buffer producătorii folosesc un capăt al buffer-ului,​ iar consumatorii celălalt capăt. 
 + 
 +O implementare de buffer circular, cu sincronizarea aferentă, se găsește în subdirectorul ''​ring-buffer/''​. Structura buffer-ului circular (''​struct rbuf''​) este declarată în fișierul header ''​ring_buffer.h'',​ împreună cu declarațiile funcțiilor. Implementarea funcțiilor se găsește în fișierul cod sursă ''​ring_buffer.c''​. 
 + 
 +În fișierul cod sursă ''​producer_consumer.c''​ se creează ''​NUM_CONSUMERS''​ thread-uri de tip consumator și ''​NUM_PRODUCERS''​ thread-uri de tip producător. În timp de ''​NUM_ROUNDS''​ runde, aceste thread-uri consumă, respectiv produc câte un element folosind buffer-ul circular. 
 + 
 +Compilăm folosind ''​make''​ și obținem fișierul executabil ''​producer_consumer''​. Rulăm acest executabil pentru a urmări folosirea cu succes a buffer-ului circular sincronizat:​ 
 +<​code>​ 
 +./​producer_consumer 
 +</​code>​
  
so/curs/sync.1587919414.txt.gz · Last modified: 2020/04/26 19:43 by razvan.deaconescu
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