Vous êtes sur la page 1sur 42

Noyau d'un systme d'exploitation INF2610 Chapitre 4 : Threads (Fils d'excution)

Dpartement de gnie informatique et gnie logiciel

Hiver 2013

Threads (Fils d'excution)

Quest ce quun threads ? Usage des threads Implmentation des threads


Au niveau utilisateur (Java) Au niveau noyau (Linux) Hybride (Solaris) Windows

Threads POSIX
Cration Attente de la fin dun fil d'excution Terminaison Nettoyage la terminaison

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 2

Quest ce quun threads ?

Le modle processus dcrit prcdemment est un programme qui sexcute selon un chemin unique (compteur ordinal). On dit quil a un fil d'excution ou flot de contrle unique (single thread). De nombreux systmes dexploitation modernes offrent la possibilit dassocier un mme processus plusieurs chemins dexcution (multithreading).

Processus et threads

1
Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 3

Quest ce quun threads ? (2)

Un thread est une unit d'excution rattache un processus, charge d'excuter une partie du programme du processus. Un processus est vu comme tant un ensemble de ressources (espace dadressage, fichiers, priphriques) que ses fils d'excution (threads) partagent. Lorsquun processus est cr, un seul fil dexcution (thread) est associ au processus. Ce fil peut en crer dautres. Chaque fil a: un identificateur unique une pile d'excution des registres (un compteur ordinal) un tat

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 4

Quest ce quun thread? (3)

Le multithreading permet lexcution simultane ou en pseudo-parallle de plusieurs parties dun mme processus.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 5

Avantages des threads / processus

Ractivit (le processus peut continuer sexcuter mme si certaines de ses parties sont bloques), Partage de ressources (facilite la coopration, amliore les performances), conomie despace mmoire et de temps. Il faut moins de temps pour : crer, terminer un fil (sous Solaris, la cration dun processus est 30 fois plus lente que celle dun thread), Changer de contexte entre deux threads dun mme processus.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 6

Le vrai cot en performance?

Processeur Intel i5, cycle de 0.4ns, LMBench Temps ns 65 170 138 778 205 1492 515 7022 1348 158 22716
Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Opration syscall trivial read write stat fstat open/close select 10 fd select 500 fd signal segfault dlai de tuyau

Opration fork+exit fork+execve pthread_create changer de processus changer de threads iadd imul idiv dadd ddiv

Temps ns 263000 269400 ~19000 ~1600 ~1400 .2 .18 9.52 1.32 12.05

Noyau d'un systme d'exploitation

Chapitre 4 - 7

Usage des threads : traitement de texte

Un thread pour interagir avec lutilisateur, Un thread pour reformater en arrire plan, Un thread pour sauvegarder priodiquement le document
Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 8

Usage des threads : Serveur Web

while(TRUE) { get_next_request(&buf); handoff_work(&buf); }

while(TRUE) { wait_for_work(&buf); look_for_page_in_cache(&buf, &page); if(page_not_in_cache(&page) read_page_from_disk(&buf, &page); return_page(&page); }


Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Noyau d'un systme d'exploitation

Chapitre 4 - 9

Implmentation des threads


Limplmentation du multi-fil (multithreading) varie considrablement dune plateforme une autre (threads Linux, threads de Win32, threads de Solaris et threads de POSIX). Le multiflot peut tre implment:
au niveau utilisateur -> modle plusieurs-- un, au niveau noyau -> modle un--un, ou aux deux niveaux (hybride) -> modle plusieurs--plusieurs.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 10

Mode utilisateur (user threads)


Les threads utilisateur sont implants dans une bibliothque (niveau utilisateur) qui fournit un support pour les grer. Ils ne sont pas grs par le noyau. Le noyau gre les processus (table des processus) et ne se proccupe pas de lexistence des threads (modle plusieurs-un). Lorsque le noyau alloue le processeur un processus, le temps dallocation du processeur est rparti entre les diffrents threads du processus (cette rpartition nest pas gre par le noyau).
Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Noyau d'un systme d'exploitation

Chapitre 4 - 11

Mode utilisateur (2)

Les threads utilisateur sont gnralement crs, et grs rapidement. Ils facilitent la portabilit (comparativement aux autres implmentations) Inconvnients :
tout instant, au plus un fil par processus est en cours dexcution. Cette implmentation nest pas intressante pour des systmes multiprocesseurs. Si un thread dun processus se bloque, tout le processus est bloqu. Pour pallier cet inconvnient, certaines librairies transforment les appels systme bloquants en appels systme non bloquants.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 12

Exemple: threads en Java


Les threads Java peuvent tre crs en : en drivant la class Thread ou implmentant linterface Runnable

Plusieurs API pour contrler les threads:

suspend() , sleep() , resume() , stop() , etc.

Les threads Java sont grs par la machine virtuelle Java (JVM).

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 13

Java Thread
import java. awt.*; class Travailleur extends Thread { public void run() { System. out. println(" Je suis le thread Travailleur"); try { Thread. sleep( 1000); } catch (InterruptedException e){} System. out. println(" Je suis le thread Travailleur"); } } public class Principal { public static void main( String args[]) { Travailleur t = new Travailleur(); t. start(); System. out. println(" Je suis le thread principal"); try { Thread. sleep( 1000); } catch (InterruptedException e){} System. out. println(" Je suis le thread principal"); } }
Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Noyau d'un systme d'exploitation

Chapitre 4 - 14

Threads en mode noyau

Les threads noyau sont directement supports par le systme dexploitation. Le systme dexploitation se charge de leur gestion. Du temps CPU est allou chaque thread. (modle un--un) Si un thread dun processus est bloqu, un autre thread du mme processus peut tre lu par le noyau Cette implmentation est plus intressante pour les systmes multiprocesseurs. Un processus peut ajuster les niveaux de priorit de ses threads. Par exemple, un processus peut amliorer son interactivit en assignant:
une forte priorit un thread qui traite les requtes des utilisateurs et une plus faible priorit aux autres.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 15

Threads en mode noyau


Inconvnients :

Performance (gestion plus coteuse) Les programmes utilisant les fils d'excution noyau sont moins portables que ceux qui utilisent des fils en mode utilisateur.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 16

Linux et les PThreads

Linux ne fait pas de distinction entre les processus et les fils d'excution qui sont communment appels tches. Il implmente le modle multiflot un--un. La cration de tches est ralise au moyen de lappel systme fork, vfork ou clone.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 17

Linux et les PThreads

vfork() fonctionne comme fork() sauf que le processus parent est bloqu jusqu ce que le processus cr appelle exit() ou exec(). Clone() permet de spcifier les ressources partager (espace dadressage, fichiers, signaux..) entre les tches cratrice et cre.

Flag CLONE_VM CLONE_FS CLONE_FILES CLONE_SIGHAND CLONE_PID

Activ Nouveau fil Partager umask, /, CWD Partager descripteurs fd Partager raction aux SIG Conserver le PID

Non activ Nouveau processus Ne pas partager Copier les fd Copier la table Fil obtient son propre PID

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 18

Mode hybride sur Solaris

Un ensemble de fils dun mme processus peuvent tre associs un fil noyau (pooling thread).

Inconvnient : mise en uvre plus complexe


Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 19

Mode hybride sur Solaris

Solaris 2 implmente le multiflot selon le modle plusieurs--plusieurs: fils utilisateur (user-level thread), processus lgers qui sont des fils noyau (LWP), et processus. Il fournit une bibliothque contenant des API pour la cration et la gestion de threads utilisateur et des LWP. La bibliothque se charge de: assigner un ou plusieurs LWP un processus, multiplexer les threads utilisateur avec les LWP disponibles pour le processus. ajuster dynamiquement le nombre de LWP fournis au processus : Si tous les LWP sont bloqus et un thread est prt lexcution, un autre LWP sera fourni au processus pour excuter ce thread. Les LWP inutiliss pendant un certain temps sont limins Chaque LWP supporte un ou plusieurs threads utilisateur et correspond un thread noyau. Le modle plusieurs--plusieurs a t abandonn, dans Solaris 8, au profit du modle un--un.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 20

Diffrence entre processus, fil d'excution pthread et fil en espace utilisateur

1 - thread_process.c
static uint64_t a = 0; int main(int argc, char **argv) { int p, i; for (i = 0; i < 2; i++) { if ((p = fork()) < 0) return EXIT_FAILURE; if (p == 0) { count(&a); printf("child %d a=%" PRId64 "\n", getpid(), a); return EXIT_SUCCESS; } } for (i = 0; i < 2; i++) { wait(NULL); } printf("a=%" PRId64 "\n", a); return EXIT_SUCCESS; } #define MAX 1000000000 void *count(void *arg) { volatile uint64_t *var = (uint64_t *) arg; volatile uint64_t i; for (i = 0; i < MAX; i++) { *var = *var + 1; } return NULL; }

2 - thread_pthread.c
static uint64_t a = 0; int main(int argc, char **argv) { int p, i; pthread_t t1, t2; pthread_create(&t1, NULL, count, &a); pthread_create(&t2, NULL, count, &a); pthread_join(t1, NULL); pthread_join(t2, NULL); printf("pid=%d a=%" PRId64 "\n", getpid(), a); return EXIT_SUCCESS; }

3 - thread_userspace.c
static uint64_t a = 0; int main(int argc, char **argv) { pth_init(); pth_t t1, t2; t1 = pth_spawn(PTH_ATTR_DEFAULT, count, &a); t2 = pth_spawn(PTH_ATTR_DEFAULT, count, &a); pth_join(t1, NULL); pth_join(t2, NULL); printf("a=%" PRId64 "\n", a); return EXIT_SUCCESS; }

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 21

Traces noyau des exemples prcdents

tat bloqu

Excution parallle

Un seul fil d'excution est cr, excution srielle


Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 22

valuation de la performance
zhukov$ time ./module2/thread_process child 23088 a=1000000000 child 23087 a=1000000000 a=0 real 0m2.507s user 0m4.900s sys 0m0.040s zhukov$ time ./module2/thread_pthread pid=23090 a=1074274083 real 0m3.791s user 0m7.240s sys 0m0.040s zhukov$ time ./module2/thread_userspace a=2000000000 real 0m4.679s user 0m4.660s sys 0m0.000s

Copies indpendantes Le calcul se fait en parallle real user / 2 Rsultat non-dterministe! Pourquoi pthread est plus lent que process ici? Le rsultat semble dterministe ici? real user

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 23

PThreads (POSIX Threads)

Lobjectif premier des Pthreads est la portabilit (disponibles sous Solaris, Linux, Windows XP ).
Description Crer un nouveau fil d'excution Terminer le fil appelant Attendre la fin d'un autre fil Crer un mutex Dtruire un mutex Verrouiller un mutex Relcher un mutex Crer une condition Dtruire une condition Attendre aprs une condition Signaler une condition
Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Appel pthread_create pthread_exit pthread_join pthread_mutex_init pthread_mutex_destroy pthread_mutex_lock pthread_mutex_unlock pthread_cond_init pthread_cond_destroy pthread_cond_wait pthread_cond_signal
Noyau d'un systme d'exploitation

Chapitre 4 - 24

Fonction pthread_create()

int pthread_create(

pthread_t *tid, // sert rcuprer le TID du pthread cr const pthread_attr_t *attr, // sert prciser les attributs du pthread `(taille de la pile, priorit.) //attr = NULL pour les attributs par dfaut void * (*func) (void*), // est la fonction excuter par le pthread void *arg); //le paramtre de la fonction.

L'appel renvoie 0 s'il russit, sinon il renvoie une valeur non nulle identifiant l'erreur qui s'est produite
Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Noyau d'un systme d'exploitation

Chapitre 4 - 25

Fonctions pthread_join() et pthread_self

void pthread_join( pthread_t tid, void * *status);

Attend la fin dun pthread. Lquivalent de waitpid des processus sauf quon doit spcifier le tid du pthread attendre. status sert rcuprer la valeur de retour et ltat de terminaison.

pthread_t pthread_self(void);

Retourne le TID du pthread.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 26

Fonction pthread_exit()
void pthread_exit( void * status); Termine l'excution du pthread

Si le pthread nest pas dtach, le TID du pthread et ltat de terminaison sont sauvegards pour les communiquer au pthread qui effectuera pthread_join. Un pthread dtach (par la fonction pthread_detach(pthread_t tid)) a pour effet de le rendre indpendant de celui qui l'a cr (pas de valeur de retour attendue). Un pthread peut annuler ou terminer lexcution dun autre pthread (pthread_cancel). Cependant, les ressources utilises (fichiers, allocations dynamiques, verrous, etc) ne sont pas libres. Il est possible de spcifier une ou plusieurs fonctions de nettoyage excuter la terminaison du pthread (pthread_cleanup_push() et pthread_cleanup_pop()).
Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Noyau d'un systme d'exploitation

Chapitre 4 - 27

Exemple pthread
// exemple_pthreads.c #define _REENTRANT #include <pthread.h> #include <unistd.h> #include <stdio.h> void afficher(int n, char lettre) { int i,j; for (j=1; j<n; j++) { for (i=1; i < 10000000; i++); printf("%c",lettre); fflush(stdout); } } void *threadA(void *inutilise) { afficher(100,'A'); printf("\n Fin du thread A\n"); fflush(stdout); pthread_exit(NULL); }
Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 28

Exemple pthread (suite)


void *threadC(void *inutilise) { afficher(150,'C'); printf("\n Fin du thread C\n"); fflush(stdout); pthread_exit(NULL); } void *threadB(void *inutilise) { pthread_t thC; pthread_create(&thC, NULL, threadC, NULL); afficher(100,'B'); printf("\n Le thread B attend la fin du thread C\n"); pthread_join(thC,NULL); printf("\n Fin du thread B\n"); fflush(stdout); pthread_exit(NULL); }

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 29

Exemple pthread (suite)

int main() { int i; pthread_t thA, thB; printf("Creation du thread A"); pthread_create(&thA, NULL, threadA, NULL); pthread_create(&thB, NULL, threadB, NULL); sleep(1); //attendre la fin des threads printf("Le thread principal attend que les autres se terminent\n"); pthread_join(thA,NULL); pthread_join(thB,NULL); exit(0); }
Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 30

Exemple pthread (suite)


Thread principal pthread_create pthread_create pthread_create

Thread B Thread A

Thread C

pthread_join pthread_exit

pthread_exit

pthread_join
Noyau d'un systme d'exploitation

pthread_exit
Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 31

Exemple pthread (suite)


-bash-3.2$ ./exemple_threads Creation du thread AACBACBACBACBACBACBACBACBACBABCABCABCABCABCABCABCA BCABCABCABCABCABCABCABCACBACBACBACBLe thread principal attend que les autres se terminent ACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBAC BACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBA CBACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBACB ACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBAC BACBACBACBA Fin du thread A CB Le thread B attend la fin du thread C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC Fin du thread C Fin du thread B -bash-3.2$
Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 32

Exemple pthread (suite)


-bash-3.2$ ./exemple_threads Creation du thread AACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBA CBACBACBACBACBACBACBACBACBACBACBACBLe thread principal attend que les autres se terminent ACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBACBAC BACBACBACBACBACBACBACBACBCABCABCABCABCABCABCABCABC ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCAB CABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCA BCABCABCABCA Fin du thread A B Le thread B attend la fin du thread C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC Fin du thread C Fin du thread B -bash-3.2$
Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 33

Exemple: partage de variables


// programme threads.c #include <unistd.h> //pour sleep #include <pthread.h> #include <stdio.h> int glob=0; void* decrement(void * x) { glob = glob - 1 ; printf("ici decrement[%u], glob = %d\n", pthread_self(),glob); pthread_exit(NULL); } void* increment (void * x) { sleep(1); glob = glob + 1; printf("ici increment[%u], glob = %d\n", pthread_self(), glob); pthread_exit(NULL); }

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 34

Exemple: partage de variables (suite)


int main( ) { pthread_t tid1, tid2; printf("ici main[%d], glob = %d\n", getpid(),glob); //creation d'un thread pour increment if ( pthread_create(&tid1, NULL, increment, NULL) != 0) return -1; printf("ici main: creation du thread[%u] avec succes\n",tid1); // creation d'un thread pour decrement if ( pthread_create(&tid2, NULL, decrement, NULL) != 0) return -1; printf("ici main: creation du thread [%u] avec succes\n",tid2); pthread_join(tid1,NULL); // attendre la fin dun thread pthread_join(tid2,NULL); printf("ici main : fin des threads, glob = %d \n",glob); return 0; -bash-3.2$ g++ thread.cpp -lpthread -o thread } -bash-3.2$ ./thread ici main[26533], glob = 0 ici main: creation du thread[3086105488] avec succes ici main: creation du thread [3075615632] avec succes ici increment[3086105488], glob = 1 ici decrement[3075615632], glob = 0 ici decrement : 3075615632 ici main : fin des threads, glob = 0
Noyau d'un systme d'exploitation Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 35

Exemple: Partage de variables (suite)


-bash-3.2$ g++ thread.cpp -lpthread -o thread -bash-3.2$ ./thread ici main[26533], glob = 0 ici main: creation du thread[3086105488] avec succes ici main: creation du thread [3075615632] avec succes ici increment[3086105488], glob = 1 ici decrement[3075615632], glob = 0 ici decrement : 3075615632 ici main : fin des threads, glob = 0 Exercice : 1)Remplacez les instructions glob = glob-1; et glob = glob+1; par respectivement : int r = glob; for(int j=0; j<10000; j++); r= r 1; glob = r; et int r = glob; for(int j=0; j<10000; j++); r= r + 1; glob = r;

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 36

Exemple: Passage de paramtres un thread


// Programme p11.1.cpp #define _REENTRANT #include <iostream> #include <cstdio> #include <cstdlib> #include <pthread.h> #include <sys/types.h> #include <sys/time.h> #include <unistd.h> using namespace std; int MAX=5; inline int gen_alea( int, int ); void *afficher( void * );

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 37

Exemple: Passage de paramtres un thread (suite)


int main(int argc, char *argv[]) { pthread_t thread_id[MAX]; int *retour; setvbuf(stdout, (char *) NULL, _IONBF, 0); if ( argc > MAX+1 ){ // verifier la liste d'arguments cerr << *argv << " arg1, arg2, ... arg" << MAX << endl; return 1; } cout << "Affichage" << endl; for (int i = 0; i < argc-1; ++i) { // creation des threads if( pthread_create(&thread_id[i],NULL,afficher, (void *)argv[i+1]) > 0) { cerr << "Echec a la creation des threads" << endl; return 2; } }

Noyau d'un systme d'exploitation Noyau d'unsystme d'exploitation

Gnie informatique et gnie logiciel Gnie Informatique et Genie Logiciel cole Polytechnique de Montral Ecole Polytechnique de Montral

Chapitre 38 Chapitre 4 -4. 38

Exemple: Passage de paramtres un thread (suite)

for (int i=0; i < argc-1; ++i) { // attendre les threads if ( pthread_join(thread_id[i], (void *) &retour) > 0){ cerr << "Echec de lattente des threads" << endl; return 3; } cout << endl << "Thread " << thread_id[i] << " retourne " << *retour; } cout << endl << "Termine" << endl; return 0; // fin de main() }

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 39

Exemple: Passage de paramtres un thread (suite)


// Afficher, un nombre alatoire de fois, un mot void * afficher(void *mot) { int *nombre = new int; *nombre = gen_alea(2,6); cout << (char *)mot << "\t sera affiche " << *nombre << " fois." << endl; for (int i=0; i < *nombre; ++i){ sleep(1); cout << (char *) mot << " "; } return (void *) nombre; } int gen_alea( int LOW, int HIGH ) { time_t seconds; time(&seconds); srand((unsigned int) seconds); return rand() % (HIGH - LOW + 1) + LOW; }
Noyau d'un systme d'exploitation

-bash-3.2$ g++ p11_1.cpp -lpthread -o p11_1 -bash-3.2$ ./p11_1 A B C Affichage A sera affiche C sera affiche 4 fois.4 fois. B sera affiche 4 fois. ACBACBACBAC Thread B 3085867920 retourne 4 Thread 3075378064 retourne 4 Thread 3064888208 retourne 4 Termine -bash-3.2$ ./p11_1 A B C Affichage C sera affiche B sera affiche 3 fois. 3 fois. A sera affiche 2 fois. BCABCA Thread 3086285712 retourne 2B C Thread 3075795856 retourne 3 Thread 3065306000 retourne 3 Termine Chapitre 4 - 40

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Exemple: Annulation dun thread


// cancel1.c int main() #define _REENTRANT { #include <pthread.h> pthread_t th; #include <unistd.h> #include <stdio.h> if void _fclose (void *arg) (pthread_create(&th,NULL,mon_thread,NULL) ) { printf("fclose\n"); fclose((FILE *)arg);} perror("Erreur dans la cration du thread"); void _unlink(void * arg) sleep(1); { printf("unlink\n"); unlink((char*)arg);}

pthread_cancel(th); // annulation

void *mon_thread(void *inutilise) -bash-3.2$ gcc cancel1.c -lpthread -o cancel1 { FILE* un_fichier; int i; -bash-3.2$ ./cancel1 setvbuf(stdout, (char *) NULL, _IONBF, 0); 0123456789 if ((un_fichier = fopen("sortie.txt","w")) == NULL) fclose perror("Erreur dans l'ouverture du fichier"); unlink else { // pour une terminaison propre pthread_cleanup_push(_unlink, (void *) "sortie.txt"); pthread_cleanup_push(_fclose, (void *) un_fichier); for (i=0; i<10000; i++){ fprintf(un_fichier,"%d",i); fprintf(stdout,"%d",i); } pthread_cleanup_pop(1); // excute fclose pthread_cleanup_pop(1); // excute unlink } } Gnie informatique et gnie logiciel Noyau d'un systme d'exploitation Chapitre 4 - 41 Ecole Polytechnique de Montral

Programmation multi-fil

Accs normal aux variables locales. Variables globales par thread qui peuvent tre accdes normalement. La mmoire alloue dynamiquement et les variables globales peuvent tre partages. Tous les accs des variables partages doivent tre protgs par un mcanisme de synchronisation qui assure la cohrence. Les fonctions de librairies doivent elles aussi tre prvues pour la programmation multi-fil.

Noyau d'un systme d'exploitation

Gnie informatique et gnie logiciel Ecole Polytechnique de Montral

Chapitre 4 - 42