Vous êtes sur la page 1sur 4

Ministère de l’Enseignement Supérieur et de la Recherche Scientifique

Sesame University
Sesame Technology
Année Universitaire : 2022/2023
Enseignant : Systèmes d’exploitation
Mohamed Chiheb TD 3 : Threads Classe(s) : 1ère ING-TA
BEN CHAABANE (Gr. E, F)

Exercice 1 (Problème Producteur-Consommateur)

Soit un système d’exploitation qui s’exécute sur une plateforme à deux processeurs.
L’ordonnanceur de ce système gère deux files d’attente, une pour chaque processeur. Il remplit celle du
premier processeur tant et aussi longtemps qu’elle n’est pas pleine. Une fois pleine, il remplit la seconde.
Quand la seconde est pleine, il revient à la première et ainsi de suite. Pour qu’une file soit pleine, il faut
qu’il y ait 4 processus en même temps dans la file.

Si le processeur est plus rapide que l’ordonnanceur, il se peut qu’une file ne soit jamais pleine.

Complétez seulement le thread ordonnanceur afin qu’il puisse produire dans les deux files
en alternance tel qu’expliqué dans le paragraphe ci haut. Les threads processeurs qui consomment les
processus sont déjà implémentés pour vous. Les prochains processus à ajouter dans les files s’accèdent
par la fonction « int prochainProc() ».
Attention : Vous ne devez pas rajouter de sémaphores additionnels, ni de variables (globales ou locales).
Vous ne devez en aucun cas utiliser la fonction sem_getvalue().

#define NB_BUFF 2
#define BUFF_SIZE 4
sem_t sem_libre[NB_BUFF];
sem_t sem_occupe[NB_BUFF];
int tab[NB_BUFF][BUFF_SIZE];
void *ordonnanceur(void *inutilise)

Page 1 sur 4
{
//buff numéro du buffer courant (buff < NB_BUFF)
// i[buff] indice dans le buffer courant. (i[buff]<BUFF_SIZE, buff =1,NB_BUFF)
int i[NB_BUFF] , buff ;
for(buff :=0 ; buff<NB_BUFF ; buff++) i[buff]=0 ;
buff=0 ;
while (1)
{

/*0*/ // Partie à compléter


}
}

void *processeur(void *arg)


{
int num = *((int *)arg); //num du buffer utilisé
int i = 0;

while(1){
sem_wait(&sem_occupe[num]);
executeProcessus(tab[num][i++%BUFF_SIZE]);
sem_post(&sem_libre[num]);
}
}
int main()
{
pthread_t thread_p;
pthread_t thread_c[NB_BUFF];
int num[NB_BUFF], i ;
for (i =0; i<NB_BUFF;i++){
sem_init(&sem_libre[i],0, BUFF_SIZE);
sem_init(&sem_occupe[i],0, 0);
num[i] = i;
pthread_create (&thread_c[i], NULL, processeur, &num[i]);
sleep(1);

Page 2 sur 4
}
pthread_create (&thread_p, NULL, ordonnanceur, NULL) ;
for (i =0; i<NB_BUFF;i++) pthread_join(thread_c[i], NULL);
pthread_join(thread_p, NULL);
}

Exercice 2 : inversion de priorité

On va maintenant illustrer le problème de l'inversion de priorité.


On met en jeu trois threads T0, T1 et T2 tels que :

Priorité de T2 > Priorité de T1 > Priorité de T0.

On utilise aussi un verrou M1.

Scénario :

main va créer les trois threads threads et le verrou M1.


Activité des threads :

Le thread T0 prend le verrou M1.

Le thread T1 fait d'abord sleep (4) puis démarre et exécute un long travail,

Le thread T2 fait d'abord sleep (2), démarre et essaie de prendre le verrou M1.

Déroulement du scénario :

Le thread T0 démarre le premier et prend le verrou M1.

Le thread T2 démarre ensuite et se bloque sur le verrou M1, déja pris par T0.

Le thread T1 démarre alors et ne s'arrête pas. Il empêche T0, qui bloque T2 de rependre son exécution. T2
le plus prioritaire ne peut plus travailler (inversion de priorité).

Page 3 sur 4
Questions :

1. Mettre en œuvre ce scénario et en constater le dysfonctionnement.


2. Donner au verrou les attributs convenables pour résoudre ce problème d'inversion de priorité.

/.Bon travail./

Page 4 sur 4

Vous aimerez peut-être aussi