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


Top Related