Programmation multi-activitesavec lesposixthreads PhilippeQueinnec ProgrammingwithPOSIXThreads,DavidButenhof,Addison- 14novembre2000 Programmingwiththreads,SteveKleiman,DevangShahetBart Wesley1997. Smaalders,PrenticeHall1996. SystemsprogrammingwithModula-3,editeparGregNelson, chapitre\anintroductiontoprogrammingwiththreads"par AndrewBirell,PrenticeHall,1991. 1
2
Tabledesmatieres I.Generalites 1Pourquoifaire?... 7 2Exemple:alarmesousUnix... 109 4Exemple:plusieursalarmes,unseulprocessus 3Exemple:plusieursalarmes.... 12 11 6Reentrance 5Threadetprocess... 14 13 7Avantagesdesactivites 8Inconvenients... 15 9Paradigmesdestructuration 16 II.POSIXthreads 1Compilation... 17 2Erreurs... 4Manipulationdesactivites... 3Lecycledevied'uneactivite... 18 a.creation... c.identication... b.terminaison 20 19 3
e.liberationdesressources d.attentedeterminaison...... 20 5Synchronisation... f.l'activiteinitiale... 21 a.necessitedeprotection b.creation/destructiond'unverrou... 22 c.creation/destructiond'unevariablecondition23 d.verrouillage/deverrouillage... e.attente/signal... 26 24 g.exemple:producteur/consommateur f.remarques... 27 h.reglesdevisibilitememoireentreactivites 28 6Primitivesannexes... 30 b.annulation(cancellation)... a.initialisation... 31 c.donneesspeciques(thread-specicdata). 32 7Activitesetsignaux... 35 a.envoidesignal... 38 b.actionassocieeaunsignal... c.quirecoitlesignal?... 39 4
e.attentesynchrone... d.masquagedessignaux... 40 8Activitesetprocesseursvirtuels... a.many-to-one... 42 41 c.many-to-few... b.many-to-many... 43 d.solaris... 45 44 III.Autressynchronisations 1Lesbarrieres... 2Verrouslecteur/redacteur... 3Semaphores... 46 5
6
I. Generalites Processus )plusieursactivites(ouprocessuslegers)auseind'un 1espaced'adressage,plusieursotsdecontr^ole. m^emeprocessusunix. 7
asynchronisme:decritlefaitquedesactivites Quelquesdenitions (ouevenements)seproduisentdemaniere synchronisation:appara^tquandilexistedes independante. parallelisme(vraiparallelisme):lefaitquedes dependancesentrelesactivites. activitess'executentsimultanement.possible concurrence(ouparallelismesimule,oupseudoparallelisme):illusionquedesactivitess'executent simultanement. uniquementsurunsystememulti-processeurs. 8
1{lesystemed'exploitation(UNIX)estasynchrone: Pourquoifaire? plusieursprocessusenconcurrence,synchronises {lemondeestasynchrone,particulierement pardestubesoudeschiers Lesactivitessontsimilairesadesprocessusmais: l'utilisateur! {ellespartagentlem^emeespaced'adressage(codes {ellespartagentlesdescripteursdechier etvariablespartagees) {ellessontmoins((co^uteuses))(souventappelees {ellesdisposentdemecanismesevoluesde ((processuslegers))) synchronisation 9
2 Exemple:alarmesousUnix Notreprogrammedoitacherunmessageapresun delailuauclavier. intmain() { intsecondes; charmsg[64]; while(1){ sleep(secondes); scanf("%d%s",&secondes,msg); } printf("alarme%d:%s\n",secondes,msg); } 10
3 Exemple:plusieursalarmes Oncreeunnouveauprocessuspourchaquealarme. Pb:commentsedebarrasserdesprocessustermines? intmain() { intsecondes; charmsg[64]; while(1){ if(fork()==0){ scanf("%d%s",&secondes,msg); sleep(secondes); exit(0); printf("alarme%d:%s\n",secondes,msg); }else{ while(waitpid(-1,null,wnohang)>0) /*ramassetouslesfilstermines*/ } /*loop*/; } } 11
4 processus Exemple:plusieursalarmes,unseul #include<pthread.h> typedefstruct{intsec;charmsg[64];}alarm_t; void*alarm_thread(void*arg) { alarm_t*al=(alarm_t*)arg; pthread_detach(pthread_self()); sleep(al->sec); printf("alarme%d:%s\n",al->sec,al->msg); free(al); } pthread_exit(null); intmain() { pthread_tthread; alarm_t*al; while(1){ al=malloc(sizeof(alarm_t)); pthread_create(&thread,null, scanf("%d%s",&(al->sec),al->msg); } alarm_thread,al); } 12
5 Threadetprocess Processus Fichiers Thread Thread Thread Signaux (masque, connection) Registres Registres Registres Données spécifiques Données spécifiques Données spécifiques Mémoire Tas Pile Pile Pile Static Code 13
6 Reentrance Siplusieursactivitess'executentsimultanement,une eventuellement^etreappeleeparunedeuxiemeactivite procedureappeleedepuisunepremiereactivitepeut Uneprocedureestreentrantesielleadmetdetelles enm^emetemps. executionssansdommage. Uneproceduremodiantdesvariablesglobalesest reentrante. generalementnonreentrante.unefonctionpureest Onplacegeneralementlesvariableslocalesdanslapile del'activiteappelante)pasdeconit. Solution:synchronisation(excl.mut.,transactions...) Unebibliotheque(ensembledeproceduresetdonnees) estreentrantesitoutessesproceduressontreentrantes lesunesvis-a-visdesautres(etd'elles-m^emes). VocabulairePosix: {MT-safe=reentrancevis-a-visduparallelisme {async-safe=reentrancevis-a-visdessignaux 14
71.utilisationd'unsystememulti-processeurs. Avantagesdesactivites 2.utilisationdelaconcurrencenaturelled'un programme.parexemple,uneactivitepeutfaire d'unee/s. descalculsalorsqu'uneautreattendleresultat 3.modeledeprogrammationnaturel,enexplicitantla synchronisationnecessaire. 81.surco^utd'execution(synchronisation,implantation Inconvenients 2.surco^utdedeveloppement:necessited'expliciter dupseudo-parallelisme). bibliotheques,dangerdesvariablespartagees. lasynchronisation,verierlareentrancedes 3.surco^utdemise-au-point:debuggagesouvent delicat(pasdeotsequentielasuivre);eet d'interferenceentredesactivites,interblocage... 15
9{travaildelegue(faiblepriorite) Paradigmesdestructuration {travailanticipe(previsiondesrequ^etesfutures) {actionsevenementiellesouperiodiques(alarmes, {ma^tre-esclaves:decompositiondutravail surveillants...) {ouvriers(workpile):ensemble(generalementxe) d'activitesrealisantlem^emetravail(lem^emecode), enextrayantdestravauxparmiunensemblede {tubesetltres:cha^ned'activites soumissions. 16
II. POSIXthreads Standarddelibrairiemulti-activites,supporteparde nombreusesimplantationsplusoumoinsconformantes DigitalUNIX4.0,AIX4.3,HP-UX11.0,IRIX6.2, (SUN/Solaris2.5,Linux(aveclinuxthreads),FreeBSD, openvms7.0...) SouventassocieaPOSIX1003.1b-1993(temps-reel), Nomociel:POSIX1003.1c-1995. 1993),POSIX1003.1j(extensions).Toussontrepris POSIX1003.1i-1995(correctionsdePOSIX1003.1b- ReprisavecquelquesajoutsdansX/OpenXSH5(aka telsquelsdansposix1003.1-1996. UNIX98). Quecontientlalibrairie: {manipulationd'activites(creation,terminaison...) {synchronisation:verrous,variablescondition. {primitivesannexes:donneesspeciquesachaque {ajustementdesprimitivesstandard:processus activite,politiqued'ordonnancement... lourd,e/s,signaux,routinesreentrantes. 17
1{inclure<pthread.h>danslessources Compilation {fairel'editiondeliensavec-lpthread {compileravec-d_reentrant 2 Erreurs ouuncode(>0)issudeerrno.h. Lesproceduresdelalibrairiepthreadrenvoie0siok, 3 Lecycledevied'uneactivite Obtention, Réveil bloqué attente de ressources: lock, wait, E/S,... Prêt préemption sur le processeur Actif exit, fin du code (détaché) exit, fin du code (non détaché) nettoyé 18 join (non détaché) terminé
4 Manipulationdesactivites a. Creation intpthread_create(pthread_t*thread, void*(*start_routine)(void*), constpthread_attr_t*attr, Creeunnouvelleactivitepourexecuterlaroutine void*arg); indiquee,appeleeavecl'argumentarg.lesattributs sontutilisespourdenirlaprioriteetlapolitique d'ordonnancement(schedulingpolicy).threadcontient l'identicateurdel'activitecreee. b. Terminaison voidpthread_exit(void*status); Terminel'activiteappelanteenfournissantuncode deretour.pthread_exit(null)estautomatiquement appeldepthread_exit. executeencasdeterminaisonducodedel'activitesans 19
c. Identication intpthread_equal(pthread_tthr1,pthread_tthr2); pthread_tpthread_self(void); selfrenvoiel'identicateurdel'activiteappelante. pthread_equalrenvoievraisilesargumentsdesignent lam^emeactivite,fauxsinon. d. Attentedeterminaison intpthread_join(pthread_tthr,void**status); Attendlaterminaisondel'activiteindiqueeetrecupere lecoderetour.l'activitenedoitpas^etredetacheeou avoirdejaete((jointe)). e. Liberationdesressources intpthread_detach(pthread_tthread); Lesressourcesalloueespourl'executiond'uneactivite Detachel'activitethread. (pile...)nesontlibereesquelorsquel'activites'est termineeetque: {oujoinaeteeectue, {oul'activiteaetedetachee. 20
f. L'activiteinitiale Audemarrage,uneactiviteestautomatiquementcreee pourexecuterlaproceduremain.elleexecuteune procedurededemarragequicontientlecode: Silaproceduremainsetermine,leprocessunix {intr=main(argc,argv);exit(r);} estensuitetermine(parl'appelaexit),etnon proceduremainneseterminealorsqu'ilrestedes passeulementl'activiteinitiale.poureviterquela activites: {bloquerl'activiteinitialesurl'attentedela terminaisond'uneouplusieursautresactivites {terminerexplicitementl'activiteinitialeavec (pthread_join); exit. pthread_exit,cequicourt-circuitel'appelde 21
5 Synchronisation Principe:moniteursdeHoarerealisesaumoyende verroux(pourassurerl'exclusionmutuelle)etde variablescondition(pourattendrequ'unetat,decrit parunpredicat,soitvrai). a. {modicationconcurrente Necessitedeprotection hx:=0x01ikhx:=0x100i {executionconcurrente )x=0x01ou0x100ou0x101ou3.1415! )x=-1,0ou1 ha:=x;x:=a+1ikhb:=x;x:=b-1i {coherencememoire )peutacher02 hx:=1;y:=2ikhprintf("%d%d",x,y);i 22
b. Creation/destructiond'unverrou pthread_mutex_tm=pthread_mutex_initializer; intpthread_mutex_init(pthread_mutex_t*mutex, intpthread_mutex_destroy(pthread_mutex_t*m); constpthread_mutex_attr*attr); (onignoreral'attribut). c. Creation/destructiond'unevariable condition pthread_cond_tvc=pthread_cond_initializer; intpthread_cond_init(pthread_cond_t*vc, intpthread_cond_destroy(pthread_cond_t*vc); constpthread_cond_attr*attr); (onignoreral'attribut). 23
d. Verrouillage/deverrouillage intpthread_mutex_lock(pthread_mutex_t*m); intpthread_mutex_trylock(pthread_mutex_t*m); lockverrouilleleverrou,avecblocageenattentesideja intpthread_mutex_unlock(pthread_mutex_t*m); trylockverrouilleleverrousipossibleetrenvoie0, verrouille.renvoie0siok. sinonrenvoieebusysileverrouestdejaverrouille(ou, commetoujours,einvalouefaultencasd'erreur). unlockdeverrouille.seulel'activitequiaverrouille dedeverrouillerunmutexverrouilleparunautre mutexaledroitdeledeverrouiller(encasdetentative thread,lecomportementestindeni). Siuneouplusieursactivitessontbloqueesenattente duverrou,uned'entreellesobtientleverrouetest debloquee.lechoixdecetteactivitedependdes prioritesetdespolitiquesd'ordonnancement.siles attributs(pourlacreationdesactivitesetdesmutex) deblocageestl'ordredeblocage(fifo),m^emesile nesontpasutilises,onconsidereraquel'ordrede systemesolarisnespeciepasuntelordre. 24
ActiviteAverrouillemutexM1 Interblocaged^uauxverrous ActiviteAsebloquesurM2 ActiviteBverrouillemutexM2 Solution:imposerunordre(acyclique)surlesverrous, ActiviteBsebloquesurM1 quidoiventnecessairement^etredemandesenrespectant cetordre. Inversiondepriorite C,tellesqueAestdefortepriorite,Bdepriorite SoittroisactivitesA,Bet moyenne,etcdefaiblepriorite,ainsiqu'unverroum. AetBsontbloquees BsereveilleetpreempteC Cs'executeetverrouillem AsereveilleetpreempteB Breprendlamain Atentedeverrouillermetsebloque etlibererleverrounecessairealapoursuitedea.la TantqueBnesebloquepas,Cnepeutpass'executer solution(rarementimplantee)consisteamodierla prioritedecpourlerendreaussiprioritairequea jusqu'acequ'ilaitlibereleverrou. 25
e. Attente/signal intpthread_cond_wait(pthread_cond_t*vc, intpthread_cond_timedwait(pthread_cond_t*vc, pthread_mutex_t*m); pthread_mutex_t*m, intpthread_cond_signal(pthread_cond_t*vc); conststructtimespec*abstime); intpthread_cond_broadcast(pthread_cond_t*vc); cond_wait:l'activiteappelantedoitpossederleverrou m.l'activitesebloquesurlavariableconditionapres avoirlibereleverrou.l'activiterestebloqueejusqu'ace quevcsoitsignaleeetquel'activiteaitreacquism. cond_timedwait:commecond_waitavecdelaide garde.al'expirationdudelaidegarde,leverrouest reobtenuetlaprocedurerenvoieetimedout. cond_signal:signalelavariablecondition:uneactivite bloqueesurlavariableconditionestreveilleeettente seraeectivementdebloqueequandellelereacquerra. dereacquerirleverroudesonappeldecond_wait.elle Pasd'ordrespeciepourlechoixdel'activitereveillee. cond_broadcast:touteslesactivitesenattentesont reveillees,ettententd'obtenirleverroucorrespondant aleurappeldecond_wait. 26
f. Remarques l'activitesignaleen'apasprioritesurlesignaleur: ContrairementaladenitiondesmoniteursdeHoare, lepossedait,etlesignalerestebloquetantqu'il lesignaleurneperdpasl'accesaumoniteurs'il n'obtientpasleverrou.c'estpourquoiilestnecessaire d'utiliseruneboucled'attentereevaluantlacondition d'execution.eneet,cetteconditionpeut^etreinvalidee entrelemomentoul'activiteestsignaleeetlemoment ouelleobtienteectivementleverrou,parexemplesi uneautreactiviteobtientlemutexetpenetredansle moniteuravantl'activitesignalee. Pourdesraisonsd'ecacite,ilestcourantdefaire l'appelacond_signalhorsdelazonelock-unlock, desortequel'activitesignaleepuisseacquerirplus facilementleverrou.attentioncependantagarantir l'atomicitedesoperationsdumoniteur! 27
g. Exemple:producteur/consommateur #include<pthread.h> #include<string.h> #include"prodcon.h" staticpthread_cond_test_libre,est_plein; staticpthread_mutex_tprotect; staticchar*buffer; /*Initialiseleproducteur/consommateur.*/ { voidinit_prodco(void) pthread_mutex_init(&protect,null); pthread_cond_init(&est_libre,null); pthread_cond_init(&est_plein,null); } buffer=null; 28
/*Deposelemessagemsg(quiestduplique). voiddeposer(char*msg) *Bloquetantqueletamponestplein.*/ { pthread_mutex_lock(&protect); while(buffer!=null) /*buffer=null*/ pthread_cond_wait(&est_libre,&protect); pthread_cond_signal(&est_plein); buffer=strdup(msg);/*duplicationdemsg*/ } pthread_mutex_unlock(&protect); /*Renvoielemessageentetedutampon. char*retirer(void) *Bloquetantqueletamponestvide.*/ { char*result; pthread_mutex_lock(&protect); while(buffer==null) /*buffer!=null*/ pthread_cond_wait(&est_plein,&protect); result=buffer; buffer=null; pthread_cond_signal(&est_libre); pthread_mutex_unlock(&protect); } returnresult; 29
h. {toutevaleurmemoirevisibleparuneactiviteavant Reglesdevisibilitememoireentreactivites unappelapthread_createestaussivisibleparla {toutevaleurmemoirevisibleparuneactivite nouvelleactiviteasondemarrage; blocagesurunevariablecondition)seraaussivisible lorsqu'ellelibereunmutex(explicitementoupar {toutevaleurmemoirevisibleparuneactivitequand partouteactivitequiverrouilleracem^ememutex; ellesignale(cond_signaloucond_broadcast)est aussivisibleparlaoulesactivitesreveilleesparce {toutevaleurmemoirevisibleparuneactivite signal; quandellesetermine(pthread_exitoundela parl'activitequila((joint))(pthread_join). procedurededepartouannulation)estaussivisible 30
6 Primitivesannexes a. Initialisation pthread_once_tonce_controle=pthread_once_init; intpthread_once(pthread_once_t*ctl, Permetd'assurerquelaprocedureinit_routineest void(*init_routine)(void)); appeleeuneetuneseulefois. vues: Rq:peut^etrerealiseeaveclesprimitivesprecedemment staticpthread_mutex_tverrou staticintinit_done=0; =PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&verrou); if(!init_done){ init_done=1; }pthread_mutex_unlock(&verrou); init_routine(); 31
b. Annulation(cancellation) intpthread_cancel(pthread_tqui); intpthread_setcancelstate(intstate, intpthread_setcanceltype(inttype, int*oldstate); voidpthread_testcancel(void); int*oldtype); voidpthread_cleanup_push(void(*routine)(void*), voidpthread_cleanup_pop(intexecute); void*arg); pthread_cancelpermetde((tuer))uneactivite. Rarementutile:l'annulationestasynchrone,preferer unesynchronisationavectestdeterminaison. 32
L'etatd'uneactivitepeut^etre(positionneavec pthread_setcancelstate): {PTHREAD_CANCEL_DISABLE:l'annulationestmise {PTHREAD_CANCEL_ENABLE:l'annulationestpriseen enattentejusqu'acequ'ellesoitautorisee. Letyped'annulationpeut^etre(positionneavec compteselonletype. pthread_setcanceltype): {PTHREAD_CANCEL_DEFERRED:l'annulationalieuau {PTHREAD_CANCEL_ASYNCHRONOUS:l'annulation prochainpointd'annulation. peutavoirlieuatoutmoment.extr^emement dangereux:impossibledeconna^trel'etatdes Lorsquel'annulationestdeclenchee,lesysteme variablespartagees. lesroutinesdenettoyageenordreinversedeleur positionnel'etatacancel_disableetexecute empilement. 33
Routinesdenettoyage: {pthread_cleanup_pushempileuneroutine; {pthread_cleanup_popdepileuneroutineet {Attention:lesappelspush/popdoiventformerdes l'executesileparametreexecuteestvrai. blocssyntaxiquementcorrects(assimilerpusha{ Pointd'annulation:certainesfonctionssontdespoints etpopa}) {pthread_testcancel {lesprocedurespthreadbloquantes((lourdes)): (paspthread_mutex_lock) pthread_cond_wait,pthread_cond_timedwait {certainesprimitivesbloquantes:wait,sigwait, {certainesprimitivespeuvent^etredespoints sleep,open,read,write... manipulationderepertoire(opendir...)... d'annulation:lalibrairiestdio(gets,printf...), 34
c. Donneesspeciques(thread-specicdata) pthread_key_tclef; intpthread_key_create(pthread_key_t*clef, intpthread_key_delete(pthread_key_tclef); void(*destructeur)(void*)); intpthread_setspecific(pthread_key_tclef, void*pthread_getspecific(pthread_key_tclef); constvoid*value); ^etredetruiteavecpthread_key_delete(rarement Uneclefestcreeeavecpthread_key_createetpeut utile). Donneesspeciques:pouruneclefdonnee(partagee), chaqueactivitepossedesaproprevaleurassocieea cetteclef(ounullenabsencedevaleurpositionnee). Lorsdelaterminaisond'uneactivite,pourchaque clefayantunevaleurassocieedanscetteactivite,le destructeurpositionnelorsdelacreationdelaclefest execute,aveclavaleurassocieeenparametre. 35
Exemple:associerunnomachaqueactivite. #include<pthread.h> #include<stdlib.h> #include"t_ident.h" staticpthread_mutex_texcl_tid; staticintnumthread=0; staticpthread_key_tkey_tid; staticpthread_once_tonce_init_tid =PTHREAD_ONCE_INIT; { staticvoidfree_tid(void*tid) if(tid!=null) } free(tid); /*Initialiselaclefpourobtenirlenom staticvoidinit_tid(void) *etlemutex.*/ { numthread=0; pthread_key_create(&key_tid,free_tid); } pthread_mutex_init(&excl_tid,null); 36
/*Getthreadid. intgettid(void) *Ifthethreadhasnoid,setitnow.*/ { int*pi; pthread_once(&once_init_tid,init_tid); pi=(int*)pthread_getspecific(key_tid); if(pi==null){ pi=malloc(sizeof(int)); pthread_mutex_lock(&excl_tid); *pi=numthread; numthread++; pthread_mutex_unlock(&excl_tid); }return*pi; pthread_setspecific(key_tid,pi); } 37
7 Activitesetsignaux Lesactivitessontdesentitesasynchronessynchronisees evenementsasynchrones,quicohabitentdicilement lorsquec'estnecessaire.lessignauxsontdes aveclesactivites. {quelleactionfaut-ilexecuter? {commentenvoyerunsignalauneactiviteprecise? {dansquelcontexte(quelleactivite)faut-ildelivrer {uneactivitepeut-ellemasquerunsignal? unsignal? {commenttraiterdemanieresynchroneladelivrance Deuxtypesdesignaux: d'unsignal? synchrones(ouderoutements):signauxdirectement SIGSEGV,SIGILL. causesparuneactiondel'activite:sigfpe,sigbus, asynchrones:signauxissusdel'exterieur(sigchld, SIGALRM,appelakill...) 38
a. Envoidesignal intpthread_kill(pthread_tthread,intsig); Nepeutsefairequ'auseindum^emeprocessusUNIX. b. Actionassocieeaunsignal Pasdechangement:onutilisesigaction(ousignal) commeprecedemment.laliaisonestfaiteauniveau gestionnairepourunensembled'activitesexecuteesau duprocessusunix:ilnepeutyavoirqu'unseul seind'unm^emeprocessusunix.l'actionpardefautest donctouteslesactivites,sigtstpsuspendleprocessus identiqueaucastraditionnel(sigkilltueleprocessus donctouteslesactivites...). c. Quirecoitlesignal? Silesignalestsynchroneouemisversuneactivite precise(pthread_kill),l'actionestexecuteeausein del'activitequiaengendrelesignal.silesignalest demasquage. masquedanscetactivite,ilresteenattentejusqu'au Silesignalestasynchrone,uneactivitequelconqueou lesignaln'estpasmasquerecoitlesignal. 39
d. Masquagedessignaux intpthread_sigmask(inthow, constsigset_t*set, /*BLOCK,UNBLOCK,SETMASK*/ Fonctionnementidentiqueasigprocmask,maismasque sigset_t*oldset); lessignauxdel'ensemblesetdansl'activiteappelante seulement. Lemasquedessignauxestheritelorsdelacreation d'unenouvelleactivite. e. Attentesynchrone Bloquel'activiteappelantejusqu'areceptiond'un intsigwait(constsigset_t*set,int*sig); dans*sig. signalparmil'ensembleset.lesignalrecuestplace Lessignauxdel'ensemblesetdoivent^etremasques danstouteslesactivites,ycomprisl'activitequiappelle sigwait. Conseil:pourmanipulerlessignauxasynchrones, utiliserexclusivementsigwait,etnonlesgestionnaires traditionnels. 40
8 Activitesetprocesseursvirtuels generalementuneentiteinterneaunoyau,appelekernel Entreleprocesseurphysiqueetlesactivites,ilexiste processouprocesseurvirtuel. Cetteentiteestgeneralementl'unitedeblocage:un appelsystemebloquant(read...)bloqueleprocesseur virtuelquil'executait. 1.Many-to-one:1seulprocesseurvirtuelpar 2.Many-to-many:1processeurvirtuelparactivite processus 3.Many-to-few:plusieursprocesseursvirtuels 41
a. Many-to-one Activité 1 Activité 2 Processeur 1 Activité 4 Activité 3 Processeur virtuel 1 +commutationentreactivitesecace Activité 5 Processeur 2 Activité 6 +implantationsimpleetportable blocageduprocessus(doncdetouteslesactivites) pasdebenecesiplusieursprocesseurs encasd'appelsystemebloquant,ouimplantation complexe 42
b. Many-to-many Activité 1 Processeur virtuel 1 Activité 2 Processeur virtuel 2 Processeur 1 Activité 4 Processeur virtuel 3 +vraiparallelismesiplusieursprocesseursphysiques Activité 3 Processeur virtuel 4 Processeur 2 Activité 5 Processeur virtuel 5 +pasdeblocagedesautresactivitesencasd'appel commutationmoinsecace(danslenoyau) bloquant ressourcesconsommeeselevees 43
c. Many-to-few Activité 1 Processeur virtuel 1 Activité 2 Processeur 1 Activité 4 Processeur virtuel 2 Activité 3 Processeur 2 +vraiparallelismesiplusieursprocesseursphysiques Activité 5 Processeur virtuel 3 Activité 6 +meilleurtempsdecommutation +meilleurrapportressources/nombred'activites +pasdeblocagedesautresactivitesencasd'appel complexe,particulierementsicreationautomatique bloquant faiblecontr^oledesentitesnoyau denouveauxprocesseursvirtuels implantationscourantessouventimparfaites 44
d. Solaris few)),avecquelquessingularites: Solaris2.6fournituneimplantationdetype((Many-to- {processeurvirtuel=lwp(light-weightprocess) {ChaqueprocessuscontientdesLWPslies(bound) {Pasdepreemptionauseind'unLWP,maisles etunpooldelwpsnondedies duprocesseurphysique LWPss'executentenconcurrenceavecpreemption {UnappelsystemebloquantbloqueleLWP responsable.certainsappels(p.e.read,passleep) {Pardefaut,lesactivitessontunbound,c'est-a-dire creentdynamiquementdeslwpsnondedies. nonlieesaunlwpparticulierets'executentdans n'importequellwpnondedie. Onpeutforceruneactiviteapossedersonpropre LWP(LWPlie): pthread_attr_tattr; pthread_attr_init(&attr); pthread_attr_setscope(&attr,pthread_scope_system); {OnpeutchangerlenombredeLWPsnondedies: pthread_create(&thr,&attr,code,arg); thr_setconcurrency(4);45
III. Autressynchronisations 1 Lesbarrieres Unebarrierebloqueunensembled'activitesjusqu'ace quetoutesaientatteintlabarriere. intbarrier_init(barrier_t*barrier, intbarrier_wait(barrier_t*b); barrier_attr_t*attr,intnombre); 2 Verrouslecteur/redacteur lecteur/redacteur Permetderealiserunesynchronisationdetype intrwlock_init(rwlock_t*lock,rwlock_attr_t*attr); intrwlock_wlock(rwlock_t*lock); intrwlock_rlock(rwlock_t*lock); intrwlock_unlock(rwlock_t*lock); intsem_init(sem_t*sem,intpshared,intvalue); 3 Semaphores intsem_post(sem_t*sem); intsem_wait(sem_t*sem); intsem_trywait(sem_t*sem); 46