Differences

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

Link to this comparison view

asc:laboratoare:02 [2021/03/16 18:46]
giorgiana.vlasceanu [Resurse]
asc:laboratoare:02 [2024/02/29 13:28] (current)
giorgiana.vlasceanu [Resurse]
Line 22: Line 22:
 Un fișier de cod Python este considerat un **modul**. Pentru a folosi alte module utilizăm ''​import''​ în următoarele modalități:​ Un fișier de cod Python este considerat un **modul**. Pentru a folosi alte module utilizăm ''​import''​ în următoarele modalități:​
  
-**Funcțiile** se declară folosind keyword-ul ''​def''​ și nu li se specifică tip de return sau tipuri ​pentru ​parametri. Se poate simula supraîncărcarea (overloading) metodelor folosind parametri cu valori implicite. Funcțiile sunt de fapt obiecte.+<spoiler Click aici pentru ​exemple ​de import-uri >
  
-Construcția **''​<nowiki>if __name__ == "​__main__"</​nowiki>''​** delimitează '​main'​-ul unui modulAceasta nu este obligatorieînsă dacă nu e folosită, orice cod cu indentare top level s-ar executa de fiecare dată când fișierul este parsat (ex: când este importat).+<code python import_example.py> 
 +import random 
 +random.randint(0,4        # trebuie specificat numele modulului
  
-<spoiler Click aici pentru exemple de funcții ​si import-uri ​>+import random as rand       # folosire alias pentru numele modulului 
 +rand.randint(0,​4) ​          # trebuie specificat alias-ul 
 + 
 +from random import *        # import tot continutul modulului 
 +randint(0,​4) ​               # nu mai trebuie specificat numele modulului 
 + 
 +from random import randint ​ # import doar randint 
 +randint(0,​4) ​       
 +</​code>​ 
 +</​spoiler>​ 
 + 
 + 
 +**Funcțiile** se declară folosind keyword-ul ''​def''​ și nu li se specifică tip de return sau tipuri pentru parametri. Se poate simula supraîncărcarea (overloading) metodelor folosind parametri cu valori implicite. Funcțiile sunt de fapt obiecte. 
 + 
 +<spoiler Click aici pentru exemple de funcții >
  
 <code python func_example.py>​ <code python func_example.py>​
Line 40: Line 56:
 </​code>​ </​code>​
  
 +</​spoiler>​
  
-<code python import_example.py> +Construcția **''​<nowiki>if __name__ == "​__main__"</​nowiki>''​** delimitează '​main'​-ul unui modulAceasta nu este obligatorieînsă dacă nu e folosităorice cod cu indentare top level s-ar executa de fiecare dată când fișierul este parsat (ex: când este importat).
-import random +
-random.randint(0,4)         # trebuie specificat numele modulului +
- +
-import random as rand       # folosire alias pentru numele modulului +
-rand.randint(0,4)           # trebuie specificat alias-ul+
  
-from random import *        # import tot continutul modulului 
-randint(0,​4) ​               # nu mai trebuie specificat numele modulului 
- 
-from random import randint ​ # import doar randint 
-randint(0,​4) ​       
-</​code>​ 
- 
-</​spoiler>​ 
  
 ===== Ce este un thread? ===== ===== Ce este un thread? =====
Line 143: Line 147:
 Un fir de execuție concurentă este reprezentat în Pyhton de clasa //Thread//. Cel mai simplu mod de a specifica instrucțiunile care se doresc a fi rulate concurent, este de a apela constructorul lui //Thread// cu numele unei funcții care conține aceste instrucțiuni,​ precum în exemplul următor. Pornirea thread-ului se face apoi cu metoda //​start()//,​ iar pentru a aștepta terminarea execuției thread-ului se folosește metoda //join()//. Un fir de execuție concurentă este reprezentat în Pyhton de clasa //Thread//. Cel mai simplu mod de a specifica instrucțiunile care se doresc a fi rulate concurent, este de a apela constructorul lui //Thread// cu numele unei funcții care conține aceste instrucțiuni,​ precum în exemplul următor. Pornirea thread-ului se face apoi cu metoda //​start()//,​ iar pentru a aștepta terminarea execuției thread-ului se folosește metoda //join()//.
  
-<code python ​exemplul1.py>+<code python ​task01.py>
 from threading import Thread from threading import Thread
   ​   ​
Line 177: Line 181:
  
 <note important>​ <note important>​
-Crearea unui obiect Thread nu pornește execuția thread-ului. ​Acestu ​lucru se întâmplă doar după apelul metodei **//​start()//​**.+Crearea unui obiect Thread nu pornește execuția thread-ului. ​Acest lucru se întâmplă doar după apelul metodei **//​start()//​**.
 </​note>​ </​note>​
  
 O metodă alternativă de a specifica instrucțiunile care se doresc a fi rulate concurent este de a crea o subclasă a lui //Thread// care suprascrie metoda //run()//. Se poate de asemenea suprascrie și metoda //<​nowiki>​__init__()</​nowiki>//​ (constructorul) pentru a primi argumentele cu care vor fi inițializate câmpurile proprii subclasei. Dacă optați pentru această abordare nu este indicat să suprascrieți alte metode ale clasei //Thread//, decât constructorul și //run()//. O metodă alternativă de a specifica instrucțiunile care se doresc a fi rulate concurent este de a crea o subclasă a lui //Thread// care suprascrie metoda //run()//. Se poate de asemenea suprascrie și metoda //<​nowiki>​__init__()</​nowiki>//​ (constructorul) pentru a primi argumentele cu care vor fi inițializate câmpurile proprii subclasei. Dacă optați pentru această abordare nu este indicat să suprascrieți alte metode ale clasei //Thread//, decât constructorul și //run()//.
  
-<code python ​exemplul2.py>+<code python ​task02.py>
 from threading import Thread from threading import Thread
   ​   ​
Line 274: Line 278:
 Exemplul de mai jos prezintă folosirea unui lock pentru a proteja accesul la o listă partajată de mai multe thread-uri. Exemplul de mai jos prezintă folosirea unui lock pentru a proteja accesul la o listă partajată de mai multe thread-uri.
  
-<code python ​exemplul3.py>+<code python ​task03.py>
 from threading import Lock, Thread from threading import Lock, Thread
  
Line 346: Line 350:
 RLock-ul devine util însă în momentul folosirii unor secțiuni critice imbricate, cauzate de funcții recursive, sau pur și simplu de organizarea codului în funcții multiple, care se apelează reciproc. În cazul folosiri RLock-ului nu mai este nevoie de urmărirea manuală stării lock-ului pentru a evita deadlock-ul ce apare la imbricarea secțiunilor critice definite de un Lock simplu. RLock-ul devine util însă în momentul folosirii unor secțiuni critice imbricate, cauzate de funcții recursive, sau pur și simplu de organizarea codului în funcții multiple, care se apelează reciproc. În cazul folosiri RLock-ului nu mai este nevoie de urmărirea manuală stării lock-ului pentru a evita deadlock-ul ce apare la imbricarea secțiunilor critice definite de un Lock simplu.
  
-<code python ​exemplul4.py>+<code python ​task04.py>
 from threading import RLock, Thread from threading import RLock, Thread
  
Line 424: Line 428:
 Un exemplu clasic de folosire a semaforului este acela de a limita numărul de thread-uri care accesează concurent o resursă precum în exemplul următor: Un exemplu clasic de folosire a semaforului este acela de a limita numărul de thread-uri care accesează concurent o resursă precum în exemplul următor:
  
-<code python ​exemplul5.py>+<code python ​task05.py>
 from random import randint, seed from random import randint, seed
 from threading import Semaphore, Thread from threading import Semaphore, Thread
Line 457: Line 461:
 ===== Exerciții ===== ===== Exerciții =====
  
-  ​Descărcați și rulați cele 5 exemple oferite în laboratorCe observați la fiecare dintre ele? + 
-  - //Hello Thread// - creați și rulați threaduri urmărind cerințele din fișierul ''​task2.py''​ din scheletul de laborator. +**Task 1**  ​Rulați exemplele task01.py task02.py task03.py task04.py task05.py
-  - //Coffee Factory// - problema ​producător-consumator folosind semafoare. + 
-      * În schelet ​este dată o implementare sumară a clasei Coffee și a unei clase ExampleCoffee. Folosind ca model, clasa ExampleCoffee,​ realizați alte 3 implementări pentru următoarele tipuri de cafea: Espresso, Americano și Cappuccino, care vor trebui să moștenească clasa de bază Coffee.+**Task 2**  ​- ​Creați și rulați threaduri urmărind cerințele din fișierul ''​task2.py''​ din scheletul de laborator. 
 + 
 +**Task 3**  ​- ​Problema ​producător-consumator folosind semafoare. 
 +      * În task3.py ​este dată o implementare sumară a clasei Coffee și a unei clase ExampleCoffee. Folosind ca model, clasa ExampleCoffee,​ realizați alte 3 implementări pentru următoarele tipuri de cafea: Espresso, Americano și Cappuccino, care vor trebui să moștenească clasa de bază Coffee.
       * CoffeeFactory funcționează ca un producător,​ iar User ca un consumator și vor trebui să realizeze operațiunile de produce și consume, mereu, fără blocaje.       * CoffeeFactory funcționează ca un producător,​ iar User ca un consumator și vor trebui să realizeze operațiunile de produce și consume, mereu, fără blocaje.
       * Implementați toate aceste clase, precum și clasa Distributor,​ care deține un buffer limitat la un număr fix de cafele, precum și de elementele de sincronizare necesare.       * Implementați toate aceste clase, precum și clasa Distributor,​ care deține un buffer limitat la un număr fix de cafele, precum și de elementele de sincronizare necesare.
       * **Important:​** Implementarea trebuie să funcționeze pentru __**oricâți**__ producători și __**oricâți**__ consumatori,​ numere care vor fi propuse de către fiecare asistent, în momentul verificării.       * **Important:​** Implementarea trebuie să funcționeze pentru __**oricâți**__ producători și __**oricâți**__ consumatori,​ numere care vor fi propuse de către fiecare asistent, în momentul verificării.
       * **Hint:** De câte semafoare am avea nevoie?       * **Hint:** De câte semafoare am avea nevoie?
-  ​- Implementați problema filozofilor.+ 
 + 
 +**Task 4**  ​- Implementați problema filozofilor.
     *  Se consideră mai mulți filozofi ce stau în jurul unei mese rotunde. În mijlocul mesei este o farfurie cu spaghete. Pentru a putea mânca, un filozof are nevoie de două bețisoare. Pe masă există câte un bețișor între fiecare doi filozofi vecini. Regula este că fiecare filozof poate folosi doar bețișoarele din imediata sa apropriere. Trebuie evitată situația în care nici un filozof nu poate acapara ambele bețișoare. Comportamentul tuturor filozofilor trebuie să fie identic.     *  Se consideră mai mulți filozofi ce stau în jurul unei mese rotunde. În mijlocul mesei este o farfurie cu spaghete. Pentru a putea mânca, un filozof are nevoie de două bețisoare. Pe masă există câte un bețișor între fiecare doi filozofi vecini. Regula este că fiecare filozof poate folosi doar bețișoarele din imediata sa apropriere. Trebuie evitată situația în care nici un filozof nu poate acapara ambele bețișoare. Comportamentul tuturor filozofilor trebuie să fie identic.
 +
 +
  
 <note important>​ <note important>​
Line 480: Line 491:
   * <​html><​a class="​media mediafile mf_pdf"​ href=":​asc:​lab2:​index?​do=export_pdf">​PDF laborator</​a></​html>​   * <​html><​a class="​media mediafile mf_pdf"​ href=":​asc:​lab2:​index?​do=export_pdf">​PDF laborator</​a></​html>​
   * {{.:​lab2-skel.zip|Schelet laborator}}   * {{.:​lab2-skel.zip|Schelet laborator}}
 +<​hidden>​
   * {{.:​lab2-sol.zip|Soluție laborator}}   * {{.:​lab2-sol.zip|Soluție laborator}}
 +</​hidden>​
 ==== Referințe ==== ==== Referințe ====
  
Line 501: Line 514:
  
   * [[http://​preshing.com/​20150316/​semaphores-are-surprisingly-versatile/​|Versatilitatea Semafoarelor]]   * [[http://​preshing.com/​20150316/​semaphores-are-surprisingly-versatile/​|Versatilitatea Semafoarelor]]
-  * [[http://​effbot.org/​zone/​thread-synchronization.htm|Mecanisme de sincronizare threaduri în Python]] 
   * [[http://​linuxgazette.net/​107/​pai.html |Understanding Threading in Python]]   * [[http://​linuxgazette.net/​107/​pai.html |Understanding Threading in Python]]
   * <​html><​a class="​media mediafile mf_pdf"​ href="​https://​www.google.ro/​url?​sa=t&​rct=j&​q=&​esrc=s&​source=web&​cd=2&​cad=rja&​uact=8&​ved=0ahUKEwi-k9vC5sbSAhUGiCwKHQK4CKYQFgghMAE&​url=http%3A%2F%2Fgreenteapress.com%2Fsemaphores%2FLittleBookOfSemaphores.pdf&​usg=AFQjCNGZLhXbpHIWv9OlMLaBdb3u2XVXyQ&​sig2=FEcdccnj-DF3X26Dp2dqQQ">​Little book of semaphores</​a></​html>​   * <​html><​a class="​media mediafile mf_pdf"​ href="​https://​www.google.ro/​url?​sa=t&​rct=j&​q=&​esrc=s&​source=web&​cd=2&​cad=rja&​uact=8&​ved=0ahUKEwi-k9vC5sbSAhUGiCwKHQK4CKYQFgghMAE&​url=http%3A%2F%2Fgreenteapress.com%2Fsemaphores%2FLittleBookOfSemaphores.pdf&​usg=AFQjCNGZLhXbpHIWv9OlMLaBdb3u2XVXyQ&​sig2=FEcdccnj-DF3X26Dp2dqQQ">​Little book of semaphores</​a></​html>​
   /** {{.:​parprocbook.pdf|Programming on Parallel Machines }}(Chapter 3) */   /** {{.:​parprocbook.pdf|Programming on Parallel Machines }}(Chapter 3) */
  
asc/laboratoare/02.1615913162.txt.gz · Last modified: 2021/03/16 18:46 by giorgiana.vlasceanu
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