Differences

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

Link to this comparison view

so:laboratoare-2013:resurse:threaduri_extra [2014/03/05 22:19]
127.0.0.1 external edit
so:laboratoare-2013:resurse:threaduri_extra [2017/04/11 10:48] (current)
adrian.stanciu [Modificarea dimensiunii și adresei de start a stivei]
Line 5: Line 5:
 ===== Terminarea thread-urilor ===== ===== Terminarea thread-urilor =====
  
-Există și posibilitatea ca un fir de execuţie să termine un alt fir, folosind mecanismul de "​__thread cancellation__"​. Pentru a face acest lucru se folosește funcţia ''​pthread_cancel''​ care primește ca parametru id-ul firului de execuţie ce urmează să fie terminat :+Există și posibilitatea ca un fir de execuţie să termine un alt fir, folosind mecanismul de "​__thread cancellation__"​. Pentru a face acest lucru se folosește funcţia ''​pthread_cancel''​ care primește ca parametru id-ul firului de execuţie ce urmează să fie terminat:
  
 <code c>int pthread_cancel(pthread_t thread);</​code>​ <code c>int pthread_cancel(pthread_t thread);</​code>​
Line 11: Line 11:
 Un thread unificabil care a fost terminat în acest mod trebuie așteptat folosind ''​pthread_join''​ pentru ca resursele folosite de el să fie eliberate. Un fir terminat cu ''​pthread_cancel''​ va întoarce valoarea PTHREAD_CANCELED. Un thread unificabil care a fost terminat în acest mod trebuie așteptat folosind ''​pthread_join''​ pentru ca resursele folosite de el să fie eliberate. Un fir terminat cu ''​pthread_cancel''​ va întoarce valoarea PTHREAD_CANCELED.
 Totuși trebuie avut grijă la folosirea acestui mecanism, întrucât un thread este posibil să fie terminat înainte de a avea posibilitatea să elibereze anumite resurse folosite. Din aceasta cauză un thread poate să controleze dacă și când poate fi terminat de către un alt thread. Totuși trebuie avut grijă la folosirea acestui mecanism, întrucât un thread este posibil să fie terminat înainte de a avea posibilitatea să elibereze anumite resurse folosite. Din aceasta cauză un thread poate să controleze dacă și când poate fi terminat de către un alt thread.
-Din punctul de vedere al posibilităţii terminării folosind ''​pthread_cancel''​ un thread poate fi :+Din punctul de vedere al posibilităţii terminării folosind ''​pthread_cancel''​ un thread poate fi:
   *cancelabil asincron - un astfel de fir poate fi terminat de către un alt fir în orice punct al execuţiei.   *cancelabil asincron - un astfel de fir poate fi terminat de către un alt fir în orice punct al execuţiei.
   *cancelabil sincron - un astfel de fir NU poate fi terminat în orice punct al execuţiei sale, ci numai în anumite puncte specifice.   *cancelabil sincron - un astfel de fir NU poate fi terminat în orice punct al execuţiei sale, ci numai în anumite puncte specifice.
   *necancelabil - un astfel de fir nu poate fi terminat folosind ''​pthread_cancel''​.   *necancelabil - un astfel de fir nu poate fi terminat folosind ''​pthread_cancel''​.
  
-Stabilirea tipului unui fir de execuţie din acest punct de vedere se face folosind funcţiile :+Stabilirea tipului unui fir de execuţie din acest punct de vedere se face folosind funcţiile:
  
 <code c> <code c>
Line 27: Line 27:
 Folosind ''​pthread_setcancelstate''​ pot fi implementate regiuni critice, în sensul că tot codul dintr-o astfel de regiune trebuie executat în întregime sau deloc, practic firul să nu poată fi terminat de către un alt fir în timp ce se găsește într-o astfel de regiune. Folosind ''​pthread_setcancelstate''​ pot fi implementate regiuni critice, în sensul că tot codul dintr-o astfel de regiune trebuie executat în întregime sau deloc, practic firul să nu poată fi terminat de către un alt fir în timp ce se găsește într-o astfel de regiune.
  
-Funcţia ''​pthread_setcanceltype''​ poate fi folosită pentru a schimba tipul de răspuns la o cerere de terminare : asincron sau sincron. Argumentul ''​type''​ indică noul tip și poate fi ''​PTHREAD_CANCEL_ASYNCHRONOUS''​ (pentru ca firul să poată fi terminat asincron, deci oricând) sau ''​PTHREAD_CANCEL_DEFERRED''​ (pentru ca o cerere de terminare sa fie amânată până când se ajunge într-un punct în care este posibilă terminarea firului). La fel, în ''​oldtype'',​ dacă nu este NULL se poate obţine starea anterioară.+Funcţia ''​pthread_setcanceltype''​ poate fi folosită pentru a schimba tipul de răspuns la o cerere de terminare: asincron sau sincron. Argumentul ''​type''​ indică noul tip și poate fi ''​PTHREAD_CANCEL_ASYNCHRONOUS''​ (pentru ca firul să poată fi terminat asincron, deci oricând) sau ''​PTHREAD_CANCEL_DEFERRED''​ (pentru ca o cerere de terminare sa fie amânată până când se ajunge într-un punct în care este posibilă terminarea firului). La fel, în ''​oldtype'',​ dacă nu este NULL se poate obţine starea anterioară.
  
 În mod implicit la crearea unui fir folosind ''​pthread_create''​ starea lui este caracterizată de ''​PTHREAD_CANCEL_ENABLE''​ și ''​PTHREAD_CANCEL_DEFERRED''​. În mod implicit la crearea unui fir folosind ''​pthread_create''​ starea lui este caracterizată de ''​PTHREAD_CANCEL_ENABLE''​ și ''​PTHREAD_CANCEL_DEFERRED''​.
Line 33: Line 33:
 Funcţiile ''​pthread_create'',​ ''​pthread_setcancelstate''​ și ''​pthread_setcanceltype''​ întorc 0 în caz de succes și un cod de eroare nenul în caz de eșec. Funcţiile ''​pthread_create'',​ ''​pthread_setcancelstate''​ și ''​pthread_setcanceltype''​ întorc 0 în caz de succes și un cod de eroare nenul în caz de eșec.
  
-În cazul în care un fir este cancelabil sincron, așa cum a fost precizat, terminarea lui se poate face numai în anumite puncte ale execuţiei sale. Practic cererile de terminare sunt amânate până se ajunge într-un astfel de punct, numit și ''​cancellation point''​. Când se ajunge într-un astfel de punct se testează dacă există cereri de terminare, și dacă da, firul este terminat. Cel mai direct mod de a crea un astfel de punct este apelând funcţia :+În cazul în care un fir este cancelabil sincron, așa cum a fost precizat, terminarea lui se poate face numai în anumite puncte ale execuţiei sale. Practic cererile de terminare sunt amânate până se ajunge într-un astfel de punct, numit și ''​cancellation point''​. Când se ajunge într-un astfel de punct se testează dacă există cereri de terminare, și dacă da, firul este terminat. Cel mai direct mod de a crea un astfel de punct este apelând funcţia:
  
 <code c> <code c>
Line 41: Line 41:
 Dacă într-un program se folosește acest mecanism de terminare a firelor folosind ''​pthread_cancel'',​ această funcţie ar trebui apelată periodic în cadrul unei funcţii asociate unui thread în care se fac multe procesări, în punctele în care firul poate fi terminat fără a rămâne resurse neeliberate și fără a produce alte efecte nedorite. Dacă într-un program se folosește acest mecanism de terminare a firelor folosind ''​pthread_cancel'',​ această funcţie ar trebui apelată periodic în cadrul unei funcţii asociate unui thread în care se fac multe procesări, în punctele în care firul poate fi terminat fără a rămâne resurse neeliberate și fără a produce alte efecte nedorite.
  
-Pe lângă ''​pthread_testcancel''​ mai există o serie de alte funcţii al căror apel reprezintă un punct de cancelare. Aceste funcţii sunt următoarele :+Pe lângă ''​pthread_testcancel''​ mai există o serie de alte funcţii al căror apel reprezintă un punct de cancelare. Aceste funcţii sunt următoarele:​
   *''​pthread_join''​   *''​pthread_join''​
   *''​pthread_cond_wait''​   *''​pthread_cond_wait''​
Line 56: Line 56:
 Atributele unui fir de execuţie (cu o excepţie) sunt specificate la crearea firului de execuţie și __nu pot fi schimbate__ pe perioada în care firul de execuţie este folosit. Atributele unui fir de execuţie (cu o excepţie) sunt specificate la crearea firului de execuţie și __nu pot fi schimbate__ pe perioada în care firul de execuţie este folosit.
  
-Pentru __iniţializarea__ și respectiv __distrugerea__ unui obiect ce reprezintă atributele unui fir de execuţie avem la dispoziţie funcţiile :+Pentru __iniţializarea__ și respectiv __distrugerea__ unui obiect ce reprezintă atributele unui fir de execuţie avem la dispoziţie funcţiile:
  
 <code c> <code c>
Line 63: Line 63:
 </​code>​ </​code>​
  
-Pentru a stabili anumite atribute specifice ale unui fir, trebuie urmaţi câţiva pași :+Pentru a stabili anumite atribute specifice ale unui fir, trebuie urmaţi câţiva pași:
  
-se creează un obiect de tipul ''​pthread_attr_t'',​ de exemplu declarând o variabilă de acest tip. +  * se creează un obiect de tipul ''​pthread_attr_t'',​ de exemplu declarând o variabilă de acest tip. 
-se apelează funcţia ''​pthread_attr_init''​ căreia i se dă ca parametru un pointer la acest obiect. Această funcţie iniţializează atributele cu valorile lor implicite. +  ​* ​se apelează funcţia ''​pthread_attr_init''​ căreia i se dă ca parametru un pointer la acest obiect. Această funcţie iniţializează atributele cu valorile lor implicite. 
-se modifică obiectul ce contine atributele folosind una din funcţiile prezentate mai jos, pentru ca să se obţină atributele dorite. +  ​* ​se modifică obiectul ce contine atributele folosind una din funcţiile prezentate mai jos, pentru ca să se obţină atributele dorite. 
-se transmite un pointer la aceste atribute funcţiei ''​pthread_create''​. +  ​* ​se transmite un pointer la aceste atribute funcţiei ''​pthread_create''​. 
-se apelează funcţia ''​pthread_attr_destroy''​ pentru a elibera obiectul ce reprezintă atributele (variabila de tip ''​pthread_attr_t''​ nu este însă dezalocată,​ ea poate fi refolosită utilizând ''​pthread_attr_init''​).+  ​* ​se apelează funcţia ''​pthread_attr_destroy''​ pentru a elibera obiectul ce reprezintă atributele (variabila de tip ''​pthread_attr_t''​ nu este însă dezalocată,​ ea poate fi refolosită utilizând ''​pthread_attr_init''​).
  
 Un același obiect de tip ''​pthread_attr_t''​ poate fi folosit pentru crearea mai multor fire de execuţie distincte și nu este necesar să fie păstrat după crearea acestora. Un același obiect de tip ''​pthread_attr_t''​ poate fi folosit pentru crearea mai multor fire de execuţie distincte și nu este necesar să fie păstrat după crearea acestora.
Line 77: Line 77:
 ==== Modificarea atributului detașabil/​unificabil ==== ==== Modificarea atributului detașabil/​unificabil ====
  
-Pentru a seta/​verifica tipul unui fir de execuţie din punct de vedere detașabil/​unificabil se pot utiliza următoarele funcţii :+Pentru a seta/​verifica tipul unui fir de execuţie din punct de vedere detașabil/​unificabil se pot utiliza următoarele funcţii:
  
 <code c> <code c>
Line 86: Line 86:
 Primul parametru este un pointer la obiectul reprezentând atributele, iar al doilea parametru reprezintă starea dorită - unificabil/​detașabil. Deoarece implicit sunt create fire unificabile (valoarea ''​PTHREAD_CREATE_JOINABLE''​),​ această funcţie trebuie apelată doar dacă se creează fire detașabile și în acest caz al doilea parametru trebuie să aibă valoarea ''​PTHREAD_CREATE_DETACHED''​. Primul parametru este un pointer la obiectul reprezentând atributele, iar al doilea parametru reprezintă starea dorită - unificabil/​detașabil. Deoarece implicit sunt create fire unificabile (valoarea ''​PTHREAD_CREATE_JOINABLE''​),​ această funcţie trebuie apelată doar dacă se creează fire detașabile și în acest caz al doilea parametru trebuie să aibă valoarea ''​PTHREAD_CREATE_DETACHED''​.
  
-Chiar dacă un fir de execuţie este creat unificabil, el poate fi transformat ulterior într-un fir detașabil apelând funcţia ''​pthread_detach''​. Însă ​o data detașat, nu mai poate fi făcut unificabil ​la loc.+Chiar dacă un fir de execuţie este creat unificabil, el poate fi transformat ulterior într-un fir detașabil apelând funcţia ''​pthread_detach''​. Însă detașat, nu mai poate fi refăcut unificabil.
  
 ==== Modificarea politicii de alocare a procesorului ==== ==== Modificarea politicii de alocare a procesorului ====
  
-Standardul POSIX definește 3 politici de alocare a procesorului :+Standardul POSIX definește 3 politici de alocare a procesorului:​
  
   *SCHED_RR - round robin   *SCHED_RR - round robin
Line 98: Line 98:
 Politicile SCHED_RR și SCHED_FIFO sunt opţionale și sunt suportate DOAR de firele de execuţie real time. Politicile SCHED_RR și SCHED_FIFO sunt opţionale și sunt suportate DOAR de firele de execuţie real time.
  
-Funcţia care este folosită pentru a schimba politica de execuţie a firelor este :+Funcţia care este folosită pentru a schimba politica de execuţie a firelor este:
  
 <code c> <code c>
Line 112: Line 112:
 ==== Modificarea priorităţii ==== ==== Modificarea priorităţii ====
  
-Pentru a schimba/​verifica prioritatea firelor de execuţie dispunem de următoarele funcţii :+Pentru a schimba/​verifica prioritatea firelor de execuţie dispunem de următoarele funcţii:
  
 <code c> <code c>
Line 125: Line 125:
 De obicei stivele firelor de execuţie încep la limita unei pagini de memorie, iar orice dimensiune a lor este rotunjită până la limita următoarei pagini. La capătul stivei este adăugată de obicei o pagină pentru care nu avem drepturi de acces și astfel cele mai multe depășiri de stivă (stack overflows) vor genera semnalul SIGSEGV (deci un segmentation fault). De obicei stivele firelor de execuţie încep la limita unei pagini de memorie, iar orice dimensiune a lor este rotunjită până la limita următoarei pagini. La capătul stivei este adăugată de obicei o pagină pentru care nu avem drepturi de acces și astfel cele mai multe depășiri de stivă (stack overflows) vor genera semnalul SIGSEGV (deci un segmentation fault).
  
-Dacă firul a fost creat unificabil stiva nu poate fi eliberată până nu se va termina un apel <tt>pthread_join</​tt> ​pentru respectivul fir.+Dacă firul a fost creat unificabil stiva nu poate fi eliberată până nu se va termina un apel ''​pthread_join'' ​pentru respectivul fir.
  
-De obicei biblioteca de fire de execuţie alocă ​1M de memorie virtuală pentru fiecare stivă de fir de execuţie.+De obicei biblioteca de fire de execuţie alocă ​2M de memorie virtuală pentru fiecare stivă de fir de execuţie.
  
 Limita minimă pentru dimensiunea unei stive a unui fir de execuţie este PTHREAD_STACK_MIN. Limita minimă pentru dimensiunea unei stive a unui fir de execuţie este PTHREAD_STACK_MIN.
  
-Pentru a seta/afla dimensiunea stivei unui fir de execuţie se pot utiliza funcţiile :+Pentru a seta/afla dimensiunea stivei unui fir de execuţie se pot utiliza funcţiile:
  
 <code c> <code c>
Line 138: Line 138:
 </​code>​ </​code>​
  
-Pentru a specifica adresa de început a unei stive se poate utiliza funcţia :+Pentru a specifica adresa de început a unei stive se poate utiliza funcţia:
  
 <code c> <code c>
so/laboratoare-2013/resurse/threaduri_extra.1394050797.txt.gz · Last modified: 2017/04/10 17:10 (external edit)
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