lab 4 fire de executie

10
Lab. 4 FIRE DE EXECUȚIE Introducere În laboratoarele anterioare a fost prezentat conceptul de proces, acesta fiind unitatea elementară de alocare a resurselor utilizatorilor. În acest laborator este prezentat conceptul de fir de execuție (sau thread), acesta fiind unitatea elementară de planificare întrun sistem. Ca și procesele, firele de execuție reprezintă un mecanism prin care se permite să se facă simultan mai multe lucruri. Un fir de execuție există în cadrul unui proces, și practic reprezintă o unitate mai fină de execuție decât procesul. În momentul în care un proces este creat, în cadrul lui există un singur fir de execuție care execută programul secvențial. Acest fir poate la rândul lui sa creeze alte fire de execuție; aceste fire vor rula același program în cadrul aceluiași proces, dar fiecare fir poate executa o parte diferită a programului. În momentul în care întrun proces este creat un nou fir de execuție, acesta va partaja spațiul de adrese, descriptorii de fișiere și alte resurse cu celelalte fire din cadrul procesului respectiv. Astfel daca un fir de execuție modifică o variabilă sau închide un fișier, aceste schimbări vor fi văzute de celelalte fire de execuție din cadrul acelui proces. În schimb, fiecare thread are propria stare a execuției (poate fi în execuție, blocat sau gata de execuție), are propriul contor program (PC) care îi indică următoarea instrucțiune ce trebuie executată, propriile valori ale regiștrilor și propria stivă. Deși un thread trebuie să se execute în cadrul unui proces, conceptele de proces și fir de execuție sunt distincte, așa cum a fost precizat deja, procesele fiind folosite pentru a grupa resurse împreuna, iar firele de execuție fiind entitățile planificate pentru execuție pe un procesor. Ceea ce aduc in plus threadurile modelului de proces este faptul că permit ca mai multe fluxuri de execuție (care pot fi întro anumită măsură independente unele de celelalte) să aibă loc în cadrul aceluiași mediu al unui proces, partajând resursele acestuia. Avantajele firelor de execuție Threadurile prezintă o serie de avantaje față de procese. Astfel, crearea firelor de execuție durează mai puțin decât crearea unor noi procese întrucât ele folosesc același spațiu de adrese; de asemenea distrugerea lor si eliberarea resurselor se face mai ușor. În cazul în care se face comutarea între threadurile unui același proces timpul de comutare este scăzut întrucât nu trebuie schimbat spațiul de adrese. Comunicarea între firele de execuție ale unui proces este si ea mult mai rapidă, si aceasta se datorează tot faptului ca ele partajează spațiul de adrese, o modificare făcută de un thread fiind imediat accesibilăși celorlalte threaduri. Firele de execuție se pot dovedi utile în multe situații, de exemplu pentru a îmbunătăți interacțiunea cu aplicațiile ce au interfețe grafice (GUI). Ele de asemenea simplifică structura unui program și conduc la utilizarea unui număr mai mic de resurse (pentru că de exemplu nu mai este nevoie de memorie partajată sau de mesaje pentru a comunica). Tipuri de fire de execuție Există 3 categorii de fire de execuție : User Level Threads (ULT) Kernel Level Threads (KLT) Fire de execuție hibride User Level Threads În cazul acestor fire, kernelul nu este conștient de existența lor și managementul lor este făcut de aplicații folosind o bibliotecă de fire de execuție. Astfel schimbarea contextului nu necesită intervenția kernelului, iar algoritmul de planificare depinde de aplicație. Avantaje :

Upload: daedalus-moon

Post on 15-Sep-2015

216 views

Category:

Documents


0 download

DESCRIPTION

Fire de executie

TRANSCRIPT

  • Lab.4FIREDEEXECUIE

    Introducere

    nlaboratoareleanterioareafostprezentatconceptuldeproces,acestafiindunitateaelementardealocarearesurselorutilizatorilor.nacest laboratoresteprezentatconceptuldefirdeexecuie(sauthread),acestafiindunitateaelementardeplanificare ntrunsistem.Ca iprocesele, fireledeexecuie reprezintunmecanismprincaresepermitesse facsimultanmaimultelucruri.

    Un fir de execuie exist n cadrul unui proces, i practic reprezint o unitatemai fin de execuie dect procesul. nmomentul ncareunprocesestecreat, ncadrul luiexistun singur firdeexecuiecareexecutprogramul secvenial.Acestfirpoate larndul luisacreezealtefiredeexecuie;acestefirevorrulaacelaiprogram ncadrulaceluiaiproces,darfiecarefirpoateexecutaopartediferitaprogramului.

    nmomentul ncare ntrunprocesestecreatunnoufirdeexecuie,acestavapartajaspaiuldeadrese,descriptoriidefiiereialteresursecucelelaltefiredincadrulprocesuluirespectiv.Astfeldacaunfirdeexecuiemodificovariabilsaunchideunfiier,acesteschimbrivorfivzutedecelelaltefiredeexecuiedincadrulaceluiproces.

    nschimb,fiecarethreadarepropriastareaexecuiei(poatefinexecuie,blocatsaugatadeexecuie),arepropriulcontorprogram(PC)careiindicurmtoareainstruciunecetrebuieexecutat,propriilevalorialeregitriloripropriastiv.

    Deiunthreadtrebuiesseexecutencadrulunuiproces,concepteledeprocesifirdeexecuiesuntdistincte,aacumafostprecizatdeja,proceselefiindfolositepentruagruparesursempreuna,iarfireledeexecuiefiindentitileplanificatepentruexecuiepeunprocesor.Ceeaceaducinplusthreadurilemodeluluideprocesestefaptulcpermitcamaimultefluxurideexecuie(carepotfintroanumitmsurindependenteuneledecelelalte)saiblocncadrulaceluiaimediualunuiproces,partajndresurseleacestuia.

    Avantajelefirelordeexecuie

    Threadurileprezintoseriedeavantajefadeprocese.

    Astfel,creareafirelordeexecuiedureazmaipuindectcreareaunornoiprocesentructelefolosescacelaispaiudeadrese;deasemeneadistrugerea lor sieliberarea resurselor se facemaiuor. n cazul n care se face comutarea ntrethreadurile unui acelai proces timpul de comutare este sczut ntruct nu trebuie schimbat spaiul de adrese.Comunicareantrefireledeexecuiealeunuiprocesestesieamultmairapid,siaceastasedatoreaztotfaptuluicaelepartajeazspaiuldeadrese,omodificarefcutdeunthreadfiindimediataccesibilicelorlaltethreaduri.

    Fireledeexecuiesepotdovediutile nmultesituaii,deexemplupentrua mbunti interaciuneacuaplicaiileceauinterfeegrafice(GUI).Eledeasemeneasimplificstructuraunuiprogramiconduc lautilizareaunuinumrmaimicderesurse(pentrucdeexemplunumaiestenevoiedememoriepartajatsaudemesajepentruacomunica).

    Tipuridefiredeexecuie

    Exist3categoriidefiredeexecuie:

    UserLevelThreads(ULT) KernelLevelThreads(KLT) Firedeexecuiehibride

    UserLevelThreads

    n cazul acestor fire, kernelul nu este contient de existena lor imanagementul lor este fcut de aplicaii folosind obibliotecdefiredeexecuie.Astfelschimbareacontextuluinunecesitinterveniakernelului,iaralgoritmuldeplanificaredepindedeaplicaie.

    Avantaje:

  • schimbareadecontextnuimplickernelul,deciavemocomutarerapid. planificareapoate fialeasdeaplicaiesidecisepoatealegeunacares favorizezecretereavitezeiaplicaiei

    noastre. firele pot rula pe orice SO, deci i pe cele care nu suport threaduri, au nevoie doar de biblioteca ce le

    implementeaz.

    Dezavantaje:

    kernelul nu tie de threaduri, deci dac un thread apeleaz ceva blocant toate threadurile din cadrul unuiprocesvorfiblocate.

    celemaimulteapeluridesistemsuntblocante,iarkernelulfaceblocarealaniveldeproces. kernelulnu tie saloce resursedectproceselor;chiardacareNprocesoareelnupoatealocaunuiproces

    dectunprocesor launmomentdat idecinu sepotexecuta nparalel2 threadurialeaceluiaiprocespeprocesoarediferite.

    KernelLevelThreads

    Managementulestefcutnacestcazdekerneliastfelnuexistniciobibliotecdethreaduri,ciunnumrdeapeluridesistem pentru utilizarea lor. Kernelulmenine informaii de context att pentru procese ct i pentru firele din cadrulproceselor,iarplanificareapentruexecuiesefacelaniveldefirdeexecuie.

    Avantaje:

    dacavemmaimulteprocesoareputem lansa nexecuiesimultanmaimulte threadurialeaceluiaiproces;blocareaunuifirnumainseamnblocareantreguluiproces.

    putemscriecodnkernelcaressebazezepethreaduri.Dezavantaje:

    comutareadecontextofacekernelul,decipentrufiecareschimbaredecontextsetrecedinfiruldeexecuienkerneliapoisemaifacencoschimbaredinkernelnaltfirdeexecuie,decivitezadecomutareestemic.

    Firedeexecuiehibride

    Acestefirencearcscombineavantajelethreaduriloruserlevelcucelealethreadurilorkernellevel.Omodalitatedeafaceacest lucruestedeautilizafirekernellevelpecaresfiemultiplexatefireuserlevel.KLTsuntunitileelementarecarepotfidistribuitepeprocesoare.Deregulcreareathreadurilorsefacenuserspaceitotaicisefaceaproapetoatplanificarea isincronizarea.Acestethreaduriuserlevelsunt invizibilepentrukernel.Kernelul tiedoardeKLTurilepecaresuntmultiplexateULT,idoarpeacestealeplanific.ProgramatorulpoateschimbaeventualnumruldeKLTalocateunuiproces.

    FunciinLinux

    POSIX

    POSIX (PortableOperating System)esteun standarddeUNIXpropusde ctre IEEE.Acest standard specific funciidebiblioteccetrebuieinclusenoricesistemUNIX.nceeaceprivetethreadurile,POSIXnuspecificdacacesteatrebuieimplementatenuserspacesaukernelspace.Linuxleimplementeaznkernelspace,darnudifereniazthreaduriledeprocesedectprin faptul c threadurilepartajeaz spaiuldeadres.Pentru folosirea threadurilor n Linux trebuie sincludemheaderul pthread.hunde se gsescdeclaraiile funciilor i tipurilordedatenecesare i sutilizmbibliotecalibpthread.

    Creareafirelordeexecuie

    Pentrucreareaunuinoufirdeexecuiesefolosestefunciapthread_create:

  • #includeintpthread_create(pthread_t*tid,constpthread_attr_t*tattr,void*(*start_routine)(void*),void*arg);

    Noul fir creat se vaexecuta concurent cu firuldeexecuiedin carea fost creat.Acesta vaexecuta codul specificatdefunciastart_routinecreia isevapasaargumentularg.Folosindargsepoatetransmitefiruluideexecuieunpointer laostructurcaresaconintoi"parametrii"necesariacestuia.

    Dac apelul are succes pthread_create ntoarce 0 i n variabila tid ntoarce identificatorul threadului, un numr ntregpozitiv.

    Prinparametrultattrsestabilescatributelenouluifirdeexecuie.DactransmitemvaloareaNULLthreadulvaficreatcuatributeleimplicite

    Ateptareafirelordeexecuie

    Lafelcalaprocese,unprinteipoateateptafiulapelndpthread_join(nlocuietewaitpid).

    intpthread_join(pthread_tth,void**thread_return);

    Primulparametruspecific identificatorul firuluideexecuieateptat, iaraldoileaparametruspecificundesevaplasacodulntorsdefunciacopil(printrunpthread_exitsauprintrunreturn).

    ncazdesuccessentoarcevaloarea0,altfelsentoarceovaloarenegativreprezentnduncoddeeroare.

    Threadurilesempartndoucategorii:

    unificabile:o permitunificareacualtethreaduricareapeleazpthread_join.o resurseleocupatedethreadnusunteliberateimediatdupterminareathreadului,cimaisuntpstrate

    pncndunaltthreadvaexecutapthread_join.o threadurilesuntimplicitunificabile.

    detaabile:o unthreadestedetaabildac:

    afostcreatdetaabil. isaschimbatacestatributntimpulexecuieiprinapelulpthread_detach.

    o nusepoateexecutaunpthread_joinpeele.o voreliberaresurseleimediatcesevortermina.

    Terminareafirelordeexecuie

    Unfirdeexecuieseterminlaunapelalfuncieipthread_exit:

    voidpthread_exit(void*retval);

    Dacnuexistunastfeldeapelesteadugatunul,nmodautomat,lasfritulcoduluifiruluideexecuie.

    Prin parametrul retval se comunic printelui unmesaj despremodul de terminare al copilului. Aceast valoare va fipreluatdefunciapthread_join.

    Existiposibilitateacaunfirdeexecuiestermineunaltfir,folosindmecanismulde"threadcancellation".Pentruafaceacest lucru se folosete funcia pthread_cancel care primete ca parametru idul firului de execuie ce urmeaz s fieterminat:

    intpthread_cancel(pthread_tthread);

    Unthreadunificabilcareafostterminatnacestmodtrebuieateptatfolosindpthread_joinpentrucaresurselefolositedeelsfieeliberate.Unfirterminatcupthread_cancelvantoarcevaloareaPTHREAD_CANCELED.

  • Totui trebuieavutgrij la folosireaacestuimecanism, ntructun threadesteposibil s fie terminat naintedeaaveaposibilitateaseliberezeanumiteresursefolosite.Dinaceastacauzunthreadpoatescontrolezedacicndpoatefiterminatdectreunaltthread.

    Dinpunctuldevederealposibilitiiterminriifolosindpthread_cancelunthreadpoatefi:

    cancelabilasincronunastfeldefirpoatefiterminatdectreunaltfirnoricepunctalexecuiei. cancelabil sincron unastfelde firNUpoate fi terminat noricepunctalexecuiei sale, cinumai nanumite

    punctespecifice. necancelabilunastfeldefirnupoatefiterminatfolosindpthread_cancel.

    Stabilireatipuluiunuifirdeexecuiedinacestpunctdevederesefacefolosindfunciile:

    intpthread_setcancelstate(intstate,int*oldstate);intpthread_setcanceltype(inttype,int*oldtype);

    Funcia pthread_setcancelstate poate fi folosit pentru a activa/dezactiva posibilitatea terminrii unui fir folosindpthread_cancel.Argumentul state reprezintnoua lui starecarepoate fiPTHREAD_CANCEL_ENABLE (pentruactivare) sauPTHREAD_CANCEL_DISABLE(pentrudezactivare).noldstate,dacnuesteNULL,sepoateobinevecheastare.

    Folosindpthread_setcancelstatepot fi implementateregiunicritice, nsensulc totcoduldintroastfelderegiune trebuieexecutatnntregimesaudeloc,practicfirulsnupoatfiterminatdectreunaltfirntimpcesegsetentroastfelderegiune.

    Funciapthread_setcanceltypepoate fi folositpentrua schimba tipulde rspuns lao cererede terminare:asincron sausincron.ArgumentultypeindicnoultipipoatefiPTHREAD_CANCEL_ASYNCHRONOUS(pentrucafirulspoatfiterminatasincron,decioricnd)sauPTHREAD_CANCEL_DEFERRED (pentrucaocererede terminaresa fieamnatpncndseajunge ntrunpunct ncareesteposibilterminareafirului).Lafel, noldtype,dacnuesteNULLsepoateobinestareaanterioar.

    nmod implicit la crearea unui fir folosind pthread_create starea lui este caracterizat de PTHREAD_CANCEL_ENABLE iPTHREAD_CANCEL_DEFERRED.

    Funciilepthread_create,pthread_setcancelstateipthread_setcanceltypentorc0ncazdesuccesiuncoddeeroarenenulncazdeeec.

    ncazulncareunfirestecancelabilsincron,aacumafostprecizat,terminarealuisepoatefacenumainanumitepunctealeexecuieisale.Practiccereriledeterminaresuntamnatepnseajungentrunastfeldepunct,numiticancellationpoint.Cndseajungentrunastfeldepunctsetesteazdacexistcererideterminare,idacda,firulesteterminat.Celmaidirectmoddeacreaunastfeldepunctesteapelndfuncia:

    voidpthread_testcancel(void);

    Dacntrunprogramsefoloseteacestmecanismdeterminareafirelorfolosindpthread_cancel,aceastfuncieartrebuiapelatperiodicncadruluneifunciiasociateunuithreadncaresefacmulteprocesri,npunctelencarefirulpoatefiterminatfrarmneresurseneeliberateifraproducealteefectenedorite.

    Pe lngpthread_testcancelmaiexistoseriedealtefunciialcrorapelreprezintunpunctdecancelare.Acestefunciisunturmtoarele:

    pthread_join pthread_cond_wait pthread_cond_timedwait sem_wait sigwait

    Deasemenea,oricefunciecareapeleazunadinacestefunciiesteieaunastfeldepunctdeterminare.

  • n general nu este o idee foarte bun folosirea funciei pthread_cancel pentru a termina un thread, dect n cazuriexcepionale.ncazurinormaleostrategiemaibunestedeaindicafiruluictrebuiessetermineiapoisseatepteterminarealui.

    Stabilireaimodificareaatributelor

    Atributelereprezintomodalitatedespecificareaunuicomportamentdiferitdecomportamentulimplicit.Atuncicndunfir de execuie este creat cu pthread_create se poate specifica un atribut pentru respectivul fir de execuie. De obiceiatributeleimplicitesuntsuficientepentrumareamajoritateaaplicaiilor.

    Atributele unui fir de execuie (cu o excepie) sunt specificate la crearea firului de execuie i nu pot fi schimbate peperioadancarefiruldeexecuieestefolosit.

    Pentru iniializarea i respectiv distrugerea unui obiect ce reprezint atributele unui fir de execuie avem la dispoziiefunciile:

    intpthread_attr_init(pthread_attr_t*tattr);intpthread_attr_destroy(pthread_attr_t*tattr);

    Pentruastabilianumiteatributespecificealeunuifir,trebuieurmaicivapai:

    1. secreeazunobiectdetipulpthread_attr_t,deexempludeclarndovariabildeacesttip.2. se apeleaz funcia pthread_attr_init creia i se d ca parametru un pointer la acest obiect. Aceast funcie

    iniializeazatributelecuvalorilelorimplicite.3. semodificobiectulcecontineatributele folosindunadin funciileprezentatemai jos,pentrucasseobin

    atributeledorite.4. setransmiteunpointerlaacesteatributefuncieipthread_create.5. se apeleaz funcia pthread_attr_destroy pentru a elibera obiectul ce reprezint atributele (variabila de tip

    pthread_attr_tnuestensdezalocat,eapoatefirefolositutilizndpthread_attr_init).

    Unacelaiobiectdetippthread_attr_tpoatefifolositpentrucreareamaimultorfiredeexecuiedistincteinuestenecesarsfiepstratdupcreareaacestora.

    ncontinuaresuntprezentatefunciilecemodificatributelecelemaiuzualealeunuifirdeexecuie.

    Modificareaatributuluidetaabil/unificabil

    Pentruaseta/verificatipulunuifirdeexecuiedinpunctdevederedetaabil/unificabilsepotutilizaurmtoarelefuncii:

    intpthread_attr_setdetachstate(pthread_attr_t*tattr,intdetachstate);intpthread_attr_getdetachstate(constpthread_attr_t*tattr,int*detachstate);

    Primulparametruesteunpointer laobiectul reprezentndatributele, iaraldoileaparametru reprezint stareadorit unificabil/detaabil.Deoarece implicitsuntcreatefireunificabile(valoareaPTHREAD_CREATE_JOINABLE),aceastfuncietrebuie apelat doar dac se creeaz fire detaabile i n acest caz al doilea parametru trebuie s aib valoareaPTHREAD_CREATE_DETACHED.

    Chiar dac un fir de execuie este creat unificabil, el poate fi transformat ulterior ntrun fir detaabil apelnd funciapthread_detach.nsodatadetaat,numaipoatefifcutunificabillaloc.

    Modificareapoliticiidealocareaprocesorului

    StandardulPOSIXdefinete3politicidealocareaprocesorului:

    SCHED_RRroundrobin SCHED_FIFOfirstinfirstout SCHED_OTHERimplementaredependentdesistem

  • PoliticileSCHED_RRiSCHED_FIFOsuntopionaleisuntsuportateDOARdefireledeexecuierealtime.

    Funciacareestefolositpentruaschimbapoliticadeexecuieafireloreste:

    intpthread_attr_setschedpolicy(pthread_attr_t*tattr,intpolicy);

    Pentru a aflapolitica curent sepoate folosi funcia pthread_attr_getschedpolicy care nmomentulde fa ntoarcedoarSCHED_OTHER.

    intpthread_attr_getschedpolicy(constpthread_attr_t*attr,int*policy);

    Modificareaprioritii

    Pentruaschimba/verificaprioritateafirelordeexecuiedispunemdeurmtoarelefuncii:

    intpthread_attr_setschedparam(pthread_attr_t*tattr,conststructsched_param*param);intpthread_attr_getschedparam(pthread_attr_t*tattr,structsched_param*param);

    PrioritateaestesemnificativdoardacpoliticafolositesteSCHED_RRsauSCHED_FIFO.

    Modificareadimensiuniiiadreseidestartastivei

    Deobiceistivelefirelordeexecuienceplalimitauneipaginidememorie,iaroricedimensiunealoresterotunjitpnlalimitaurmtoareipagini.Lacaptulstiveiesteadugatdeobiceiopaginpentrucarenuavemdrepturideaccesiastfelcelemaimultedepiridestiv(stackoverflows)vorgenerasemnalulSIGSEGV(deciunsegmentationfault).

    Dacfirulafostcreatunificabilstivanupoatefieliberatpnnusevaterminaunapelpthread_joinpentrurespectivulfir.

    Deobiceibibliotecadefiredeexecuiealoc1Mdememorievirtualpentrufiecarestivdefirdeexecuie.

    LimitaminimpentrudimensiuneauneistiveaunuifirdeexecuieestePTHREAD_STACK_MIN.

    Pentruaseta/afladimensiuneastiveiunuifirdeexecuiesepotutilizafunciile:

    intpthread_attr_setstacksize(pthread_attr_t*tattr,intstacksize);intpthread_attr_getstacksize(pthread_attr_t*tattr,size_t*size);

    Pentruaspecificaadresadenceputauneistivesepoateutilizafuncia:

    intpthread_attr_setstackaddr(pthread_attr_t*tattr,void*stackaddr);

    Cedareaprocesorului

    Pentruacedavoluntarprocesorulsepoatefolosifuncia:

    #includeintsched_yield(void);

    Dacexistalteprocese interesatedeprocesoracesta li seofer,dacnuexistniciunaltproces nateptarepentruprocesor,firulcurenticontinuexecuia.

    ncazdesuccesfunciantoarcevaloarea0,altfel1(ierrnoiavaloareacoduluideeroare).

    Alteoperaii

  • Dacdorimsfimsiguricuncoddeiniializareseexecutosingurdatputemfolosifuncia:

    pthread_once_tonce_control=PTHREAD_ONCE_INIT;intpthread_once(pthread_once_t*once_control,void(*init_routine)(void));

    Scopulfuncieipthread_onceestedeaasiguracobucatdecod(deobiceifolositpentruiniializri)seexecuteosingurdat.Argumentulonce_controlesteunpointer laovariabil iniializatcuPTHREAD_ONCE_INIT.Primaoarcndaceastfuncieesteapelateavaapela funcia init_routine iva schimbavaloareavariabileionce_controlpentrua ineminte ciniializareaaavutloc.Urmtoareleapelurialeacesteifunciicuacelaionce_controlnuvorfacenimic.

    Funciapthread_oncentoarcentotdeauna0.

    Pentruadeterminaidentificatorulthreaduluicurentsepoatefolosifuncia:

    pthread_tpthread_self(void);

    Pentruadeterminadacdoiidentificatorisereferlaacelaithreadsepoatefolosi:

    intpthread_equal(pthread_tthread1,pthread_tthread2);

    Pentruaflarea/modificareaprioritilorsuntdisponibileurmtoareleapeluri:

    intpthread_setschedparam(pthread_ttarget_thread,intpolicy,conststructsched_param*param);intpthread_getschedparam(pthread_ttarget_thread,int*policy,structsched_param*param);

    ThreadSpecificData

    Aa cum a fostprecizatdeja, spredeosebiredeprocese, fireledeexecuiedin cadrulunuiprogrampartajeaz acelaispaiudeadrese,decimodificareauneivariabiledectreunfirestevizibilicelorlaltefire.Totui,fireledeexecuieaupropria lorstiv, faptce lepermitesexecutecoddiferit,sapeleze funciiceaupropriilevariabile locale (pstratepestiv).

    Uneorinsesteutilcaovariabilsfieduplicatastfelnctfiecarethreadsaibproprialuicopieseparat.nLinuxestepermis acest lucru prin folosirea unei zone numite thread specific data (TSD).Variabilele stocate n aceast zon suntduplicatepentrufiecarefirdeexecuieifiecarefirpoatesmodificecopialuifraafectacelelaltethreaduri.

    PentruaaccesavariabilelestocatenTSDexistoseriedefunciispecifice.

    PotficreateorictevariabileTSD,acesteafiinddetipulvoid*.Fiecarevariabilpoatefiaccesatprinintermediuluneicheidetipulpthread_key_t.

    Pentruacreaonoucheie,idecionouvariabilTSD,sefolosetefuncia:

    intpthread_key_create(pthread_key_t*key,void(*destr_function)(void*));

    Primulparametruesteunpointerlaovariabildetippthread_key_t.ValoareaacesteicheivafiapoifolositdefirepentruaaccesapropriacopieavariabileidetipTSDrespective.Aldoileaparametrureprezintofunciedecleanup.Dacaiciestedatunpointer lao funcie, aceast funcie va fi automat apelat cnd fiecare fir se termin i vaprimi caparametruvaloarea corespunztoare cheii specific firului respectiv.Dac valoarea specific firuluiesteNULL, funcianumaiesteapelat.Dacnuestenecesarofunciedecleanup,aldoileaparametrualluipthread_key_createpoatefiNULL.

    Dup crearea cheii fiecare fir de execuie poate modifica propria copie a variabilei asociate cheii folosind funciapthread_setspecific:

    intpthread_setspecific(pthread_key_tkey,constvoid*pointer);

  • Primulparametrureprezintcheia,iaraldoileaparametrureprezintvaloareaspecificcetrebuiestocaticareestedetipulvoid*.

    PentruadeterminavaloareauneivariabiledetipTSDsefolosetefuncia:

    void*pthread_getspecific(pthread_key_tkey);

    funcieceprimetecaparametrucheiacorespunztoarevariabileispecifice.

    Funcia:

    intpthread_key_delete(pthread_key_tkey);

    dezalococheieTSD.Eanuapeleazfunciadecleanupasociatacesteia.

    Funciilepthread_create_key,pthread_key_deleteipthread_setspecificntorc0ncazdesuccesiuncoddeeroarenenulncazdeeec.Funciapthread_getspecificntoarcevaloareaasociatcheiincazdesuccesiNULLncazdeeec.

    Funciipentrucleanup

    FunciiledecleanupasociateTSDurilorpotfifoarteutilepentruaasigurafaptulcresurselesunteliberateatuncicndunfirseterminsingursauesteterminatdectreunaltfir.Uneoripoatefiutilssepoatspecificaastfeldefunciifracreaneapratunthreadspecificdata.Pentruacestscopexistafunciiledecleanup.

    Oastfeldefunciedecleanupesteofunciecareesteapelatcndunthreadsetermin.Eaprimeteunsingurparametrudetipulvoid*careestespecificatlanregistrareafunciei.

    Ofunciedecleanupestefolositpentruaeliberaoresursnumaincazulncareunfirdeexecuieapeleazpthread_exitsauesteterminatdeunalt fir folosindpthread_cancel. ncircumstanenormale,atuncicndun firnusetermin nmodforat,resursatrebuieeliberatexplicit,iarfunciadecleanuptrebuiesafiescoas.

    Pentruanregistraoastfeldefunciedecleanupsefolosete:

    voidpthread_cleanup_push(void(*routine)(void*),void*arg);

    Aceasta funcie primete ca parametri un pointer la funcia care este nregistrat i valoarea argumentului care va fitransmis acesteia. Funcia routine va fi apelat cu argumentul arg atunci cnd firul este terminat forat. Daca suntnregistratemaimultefunciidecleanup,elevorfiapelatenordineLIFO(deciceamairecentinstalatvafiprimaapelat).

    Pentrufiecareapelpthread_cleanup_pushtrebuiesexisteiapelulcorespunztorpthread_cleanup_popcaredenregistreazofunciedecleanup:

    voidpthread_cleanup_pop(intexecute);

    Aceastfuncievadenregistraceamairecent instalatfunciedecleanup,idacaparametrulexecuteestenenulovaiexecuta.

    Atentie!Unapelpthread_cleanup_push trebuie saibunapel corespunztorpthread_cleanup_pop naceeai funcie i laacelainiveldeimbricare.

    Unmicexempludefolosireafunciilordecleanup:

    void*alocare_buffer(intsize){ returnmalloc(size);}

  • voiddealocare_buffer(void*buffer){ free(buffer);}/*functiaapelatadeunthread*/voidfunctie(){ void*buffer=alocare_buffer(512); /*inregistrareafunctieidecleanup*/ pthread_cleanup_push(dealocare_buffer,buffer); /*aiciaulocprelucrari,sisepoateapelapthread_exitsaufirulpoatefiterminatdeunaltfir*/ /*deinregistrareafunctieidecleanupsiexecutiaei(parametruldatestenenul)*/ pthread_cleanup_pop(1);}

    Compilare

    Lacompilaretrebuiespecificatibibliotecalibpthread(decisevafolosiargumentullpthread).

    Atentie!Nulinkaiunprogramsinglethreadedcuaceastbibliotec.Dacafaceiaacevasevorstabilinitemecanismemultithreadingcarevorfiiniializatelaexecuie.Atunciprogramulvafimultmailent,vaocupamultmaimulteresurseivafimultmaidificildedebugat.

    Exemplu

    ncontinuareesteprezentatunexemplusimplu ncaresuntcreate2 firedeexecuie, fiecareafinduncaracterdeunanumitnumrdeoripeecran.

    #include;#include;/*structuracecontineparametriitransmisifiecaruithread*/structparametri{ charcaracter;/*caracterulafisat*/ intnumar;/*decateorivafiafisat*/};/*functiaexecutatadethreaduri*/void*afisare_caracter(void*params){ structparametri*p=(structparametri*)params; inti; for(i=0;inumar;i++) printf("%c",p>caracter); printf("\n"); returnNULL;}intmain(){ pthread_tfir1,fir2; structparametrifir1_args,fir2_args; /*creamunthreadcarevaafisa'x'de11ori*/

  • fir1_args.caracter='x'; fir1_args.numar=11; if(pthread_create(&fir1,NULL,&afisare_caracter,&fir1_args)){ perror("pthread_create"); exit(1); } /*creamunthreadcarevaafisa'y'de13ori*/ fir2_args.caracter='y'; fir2_args.numar=13; if(pthread_create(&fir2,NULL,&afisare_caracter,&fir2_args)){ perror("pthread_create"); exit(1); } /*asteptamterminareacelordouafiredeexecutie*/ if(pthread_join(fir1,NULL)) perror("pthread_join"); if(pthread_join(fir2,NULL)) perror("pthread_join"); return0;}

    Comandautilizatpentruacompilaacestexempluvafi:

    gccoexempluexemplu.clpthread