Systèmes d’Exploitation: TP 3 - Threads et synchronisation

Utilisation de Git

Le rendu du TP se fera avec GIT. Pour ce TP il faut travailler sur le répertoire TP3. Après chaque question il faut faire un commit avec le code C demandé et éventuellement les réponses aux questions dans un fichier texte.

Partie I: Threads et problèmes de concurrence

  1. Écrivez un programme C qui prends un entier N en paramètre et crée N threads. À la création vous attribuerez à chaque thread un numéro unique. Chaque thread imprimera le message “Bonjour, je suis le thread numéro ???”.

Vous pouvez vous servir des appels de bibliothèque suivants: pthread_create et pthread_join.

Exemple d’exécution attendue:

$ ./exo1 10
Bonjour je suis le thread numéro 1
Bonjour je suis le thread numéro 4
Bonjour je suis le thread numéro 0
Bonjour je suis le thread numéro 3
Bonjour je suis le thread numéro 2
Bonjour je suis le thread numéro 5
Bonjour je suis le thread numéro 7
Bonjour je suis le thread numéro 6
Bonjour je suis le thread numéro 9
Bonjour je suis le thread numéro 8

Exécutez votre programme plusieurs fois, que constatez vous ? Que se passe-t-il si vous omettez l’appel à pthread_join en fin de programme ?

  1. Dans cet exercice on va reprendre le programme précédent et rajouter une variable globale int compteur. Modifiez le code de chaque thread pour qu’il incrémente et affiche la variable compteur. Enfin, imprimez la valeur finale de compteur dans le main après avoir attendu la terminaison de tous les threads avec pthread_join.

Exemple d’exécution attendue:

$ ./exo2 10
1
5
3
4
2
6
7
8
9
10
Le compteur vaut 10

Augmentez progressivement le nombre de threads crées ? Qu’observez vous ? Comment expliquez vous ce phénomène ?

  1. Utilisez les fonction pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock et pthread_mutex_destroy pour protéger l’accès à la section critique (incrément du compteur partagé) dans le programme précédent.

Comparez le temps d’exécution entre la version avec et sans mutex (vous pouvez utiliser /usr/bin/time).

Partie II: Problème Producteur Consommateur

Soit un programme avec deux types de threads. Des threads producteurs et des threads consommateurs.

Ici les objets à produire sont des numéros uniques allant de 0 à MAX_OBJETS-1.

Les producteurs et consommateurs communiquent uniquement à travers une pile LIFO (last-in-first-out) partagée par tous les threads du programme. La pile aura une taille paramétrable LIFO_SIZE. La pile sera implémentée à l’aide d’un tableau d’entiers.

Le programme prends trois arguments:

Chaque thread producteur a la mission suivante:

Chaque threads consommateurs a la mission suivante:

Pour cet exercice vous utiliserez uniquement les primitives de synchronisation définies dans semaphore.h.

  1. Écrire une version du programme simplifié qui marche avec 1 consommateur et 1 producteur. Montrez que votre programme marche dans tous les cas de figure et qu’il termine normalement.

  2. Généralisez votre programme pour qu’il marche avec N consommateur et M producteurs. Montrez que votre programme marche dans tous les cas de figure et qu’il termine normalement.

Voici un exemple d’exécution avec 3 producteurs et 2 consommateurs:


$ ./prodcons 20 3 2
Consommateur 1 crée
Producteur 0 crée
(0) Produit [19]
(0) Produit [18]
(0) Produit [17]
(0) Produit [16]
(0) Produit [15]
(0) Produit [14]
Consommateur 0 crée
Producteur 1 crée
Producteur 2 crée
(0) Produit [13]
(0) Produit [12]
(0) Produit [11]
(0) Produit [10]
(1) Produit [9]
(0) Consomme [9]
(0) Consomme [10]
(1) Consomme [11]
(1) Produit [8]
(1) Produit [7]
(1) Produit [6]
(1) Produit [5]
(1) Produit [4]
(1) Produit [3]
(1) Produit [2]
(1) Produit [1]
(1) Produit [0]
(0) Consomme [0]
(0) Consomme [1]
(0) Consomme [2]
(0) Consomme [3]
(1) Consomme [4]
(1) Consomme [5]
(1) Consomme [6]
(1) Consomme [7]
(1) Consomme [8]
(1) Consomme [12]
(1) Consomme [13]
(1) Consomme [14]
(1) Consomme [15]
(1) Consomme [16]
(1) Consomme [17]
(1) Consomme [18]
(1) Consomme [19]
(0) Consomme [0]
  1. Donnez un exemple de “vrai” programme qui utilise le modèle producteur-consommateur que vous venez d’écrire.