Vous êtes sur la page 1sur 7

Systèmes D’Exploitation II - 2ème année Licence

Travaux Dirigés II
ESEN - Université de la Manouba
Amine DHRAIEF

Partie théorique
1. Qu’est ce qu’un multithreading ? et quelle est la différence avec la multiprogrammation ?

Solution: Multithreading : exécution concurrente/parallèle de plusieurs threads à


l’intérieur d’un même processus alors que la multiprogrammation c’est l’exécution
concurrente de plusieurs processus sur un monoprocesseur.

2. Quelles sont les principales similarités/différences entre un processus et un thread ? Dans


une application qui partage des données en mémoire, faut-il privilégier les processus ou
les threads ?

Solution: Un processus est une unité de structuration, défini techniq. par un seg.
Code, un seg. Data et un seg. Pile d’exécution et un contexte alors qu’un thread (ou
encore processus léger) est une unité d’exécution qui partage avec tous les autres
threads d’un même processus l’espace d’adressage mémoire mais il ne contient que
sa pile d’exécution, son CO,... On privilégie les threads par rapport aux processus
afin de gagner en performance en particulier la commutation est moins coûteuse.

3. Décrire ce qu’est un TCB (Thread Control Bloc) en vous inspirant du contenu d’un PCB
(Process Control Bloc ou encore un Descripteur de Processus).

Solution: TCB : Program Counter + CPU register + CPU scheduling information


+ Pending I/O information

4. Considérez les deux morceaux de code suivants. Deux threads exécutent respectivement
les fonctions writer_thread() et reader_thread(), et partagent la variable pointer.
int *pointer = NULL;
void * writer_thread() {
while (1) {
if (pointer == NULL) {
pointer = malloc(sizeof(int));
*pointer = rand();
//fonction dans stdlib.h pour recevoir une valeur aléatoire
}
}
}
void *reader_thread() {
while (1) {
if (pointer != NULL) {
printf("pointer = %d", *pointer);
free(pointer);
pointer = NULL;
}
}
}

(a) En exécutant le programme qui crée deux threads ayant les fonctions précédentes,
une erreur "Erreur de segmentation" apparaît au bout d’un certain temps. D’où
provient cette erreur ? Expliquer.

Solution: Le lecteur peut effectuer l’appel à free() pendant que l’écrivain est
bloqué dans random().

Partie pratique
5. La création et le lancement du thread se fait par :

pthread_t th1 ;
int ret ;
pthread_create (&th1, NULL, runDuThread, "1");
if (th1 == NULL) {
fprintf (stderr, "pthread_create error 1") ; exit(0) ;}

Le thread exécutera alors la fonction runDuThread dont le prototype est :


void* runDuthread (void *param) ;
Cette fonction est à écrire par le programmeur pour décrire le comportement du thread.
Le paramètre param est un pointeur dont la valeur est celle passée en argument (le 4ème)
de la fonction pthread_create. Il permet de passer des données au thread.
Si la fonction main se termine, le programme et tous les threads lancés se terminent
aussi. Il faut donc s’assurer avant de terminer le programme que tous les threads ont fini
leur travail. L’attente de la terminaison d’un thread se fait comme ceci :
(void) pthread_join (th1, (void *)&ret) ;
Le paramètre ret contiendra la valeur retournée par la fonction pthread_exit(int val)
à exécuter avant de terminer un thread.
(a) Écrire un programme qui lance 2 threads. L’un écrira les 26 minuscules à l’écran et
l’autre les 26 majuscules.

Page 2
#i n c l u d e <pt hr ea d . h>
#i n c l u d e <s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <s t d i o . h>
#i n c l u d e < s t r i n g . h>
#i n c l u d e <u n i s t d . h>

void ∗ affiche_min ( )
{
cha r c ;
f o r ( c =’a ’ ; c<=’z ’ ; c++)
p r i n t f ("%c " , c ) ;
pt hr ea d_ exit (NULL ) ;

void ∗ affiche_maj ( )
{
cha r c ;
f o r ( c =’A ’ ; c<=’Z ’ ; c++)
p r i n t f ("%c " , c ) ;
pt hr ea d_ exit (NULL ) ;

}
i n t main ( v o i d )
{
int i ;
i nt ret1 , ret2 ;
/∗ v o i d ∗ r e t o u r 1 ;
void ∗ retour2 ;∗/
pthread_t thread1 , t h r e a d 2 ;
i f ( ( r e t 1 = p t h r e a d _ c r e a t e (& thread1 , NULL, a f f iche_ min , NULL) ) !=
{
f p r i n t f ( s t d e r r , "%s \n " , s t r e r r o r ( r e t 1 ) ) ;
exit (1);
}

i f ( ( r e t 2 = p t h r e a d _ c r e a t e (& thread2 , NULL, a f f iche_ ma j , NULL) ) !=


{
f p r i n t f ( s t d e r r , "%s \n " , s t r e r r o r ( r e t 2 ) ) ;
exit (1);
}

Page 3
pt hr ea d_ j o in ( t h r e a d 1 , NULL ) ;

pt hr ea d_ j o in ( t h r e a d 2 , NULL ) ;

return ( 0 ) ;
}

(b) Écrire un programme qui initialise une variable globale à 0 et crée 2 threads. Chacun
des threads va incrémenter la variable N fois. Afficher la valeur de la variable à la
fin de l’exécution de chacun des threads.
#i n c l u d e <pt hr ea d . h>
#i n c l u d e <s t d i o . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <u n i s t d . h>

void ∗ fonction_thread ( void ∗ arg ) ;

#d e f i n e NB_THREADS 2
i n t var_globale ;
i n t main ( v o i d )
{
pthread_t t h r [NB_THREADS ] ;
int i , j ;
i n t v a r _ g l o b a l e =0;
cha r c h a i n e [ 1 2 8 ] ;

f p r i n t f ( st do ut , " Ent r ez l e nombre d ’ i n c r é m e n t a t i o n de v a r _ g l o b a l e : " ) ;


w h i l e ( f g e t s ( cha ine , 1 2 8 , s t d i n ) != NULL)
i f ( s s c a n f ( cha ine , "%d " , & i ) != 1 )
f p r i n t f ( st do ut , "un nombre SVP \n " ) ;
else
break ;

f o r ( j = 0 ; j < NB_THREADS ; j ++) {


i f ( p t h r e a d _ c r e a t e(& t h r [ j ] , NULL, f o n c t i o n _ t h r e a d , ( v o i d ∗)& i ) != 0 )
{
f p r i n t f ( s t d e r r , " Er r eur dans p t h r e a d _ c r e a t e \n " ) ;
e x i t (EXIT_FAILURE ) ;
}
}

f o r ( j = 0 ; j < NB_THREADS ; j ++) {


pt hr ea d_ j o in ( t h r [ j ] , NULL ) ;

Page 4
}

void ∗ fonction_thread ( void ∗ arg )


{
i n t borne_sup = ∗ ( ( i n t ∗ ) a r g ) ;
i n t i =0;
f o r ( i =0; i <borne_sup ; i ++)
{
v a r _ g l o b a l e++;
}
p r i n t f ( " La v a l e u r de v a r _ g l o b a l e e s t = %d\n " , v a r _ g l o b a l e ) ;
pt hr ea d_ exit (NULL ) ;
}

La suite de Fibonacci
6. La suite de Fibonacci est une suite d’entiers dans laquelle chaque terme est la somme
des deux termes qui le précèdent : 0, 1, 1, 2, 3, 5, 8. Formellement, on exprime cette
suite comme suit :
fib[0]=0
fib[1]=1
fib[n]=fib[n-1]+fib[n-2]

Écrire un programme multithreadé qui génère la séquence de Fibonacci. Ce programme


devrait fonctionner comme suit : L’utilisateur saisira le nombre d’éléments de la suite de
Fibonacci que le programme devra générer.
Le programme va alors créer un thread séparé qui va générer les nombres de Fibonacci,
plaçant la séquence dans une structure de données qui peut être partagées par les fils
(un tableau est probablement la structure de données la plus commode).
Lorsque le thread termine son exécution, la thread principal affichera le résultat.
#i n c l u d e <pt hr ea d . h>
#i n c l u d e <s t d i o . h>
#i n c l u d e <s t d l i b . h>
#i n c l u d e <u n i s t d . h>
#i n c l u d e <s t r i n g . h>
#d e f i n e MAX_ELEMENT 100

v o i d ∗ fn_thread ( v o i d ∗ ind )
{
int i , fib , fib1 , fib2 ;

Page 5
i n t ∗ tab ;
int indice ;
i n d i c e =∗(( i n t ∗ ) ind ) ;
tab=c a l l o c (MAX_ELEMENT, s i z e o f ( i n t ) ) ;
i f ( i n d i c e ==0){tab [ 0 ] = 0 ; }
e l s e i f ( i n d i c e ==1){tab [ 0 ] = 0 ; tab [ 1 ] = 1 ; }
else {
f i b 1 =0;
f i b 2 =1;
f i b =0;
tab [ 0 ] = 0 ;
tab [ 1 ] = 1 ;
p r i n t f ( " tab [ 0 ] == %d\n " , tab [ 0 ] ) ;
p r i n t f ( " tab [ 1 ] == %d\n " , tab [ 1 ] ) ;
f o r ( i =2; i<=i n d i c e ; i ++)
{
f i b=f i b 1+f i b 2 ;
f i b 1=f i b 2 ;
f i b 2=f i b ;
tab [ i ]= f i b ;
p r i n t f ( " tab[%d ] == %d\n " , i , tab [ i ] ) ;
}
}

f o r ( i =0; i<=i n d i c e ; i ++)


{
p r i n t f ( " Thread −−> tab [%d]==%d\n " , i , tab [ i ] ) ;
}
pt hr ea d_ exit ( ( v o i d ∗ ) tab ) ;
}

i n t main ( v o i d )
{
int indice , i ;
void ∗ retour ;
int ∗ tab ;
pthread_t t h r e a d ;

cha r c h a i n e [ 1 2 8 ] ;

f p r i n t f ( st do ut , " Ent r ez l e nombre d ’ élement de l a s u i t e F i b o n a c


w h i l e ( f g e t s ( cha ine , 1 2 8 , s t d i n ) != NULL)
i f ( s s c a n f ( cha ine , "%d " , & i n d i c e ) != 1 )
f p r i n t f ( st do ut , "un nombre SVP \n " ) ;

Page 6
else
break ;

i f ( p t h r e a d _ c r e a t e(& thread , NULL, fn_thread , ( v o i d ∗)& i n d i c e )


f p r i n t f ( s t d e r r , " Er r eur dans p t h r e a d _ c r e a t e \n " ) ;
e x i t (EXIT_FAILURE ) ;

pt hr ea d_ j o in ( t h r e a d , &r e t o u r ) ;
tab=( i n t ∗ ) r e t o u r ;
f o r ( i =0; i<=i n d i c e ; i ++)
{
p r i n t f ( " tab [%d]==%d\n " , i , tab [ i ] ) ;
}
f r e e ( tab ) ;
return 0;
}

Page 7

Vous aimerez peut-être aussi