TP ‐ Threads - vbridonneau/CoursSysteme GitHub Wiki
- Quelles sont les fonctions de qu'il faut appeler pour :
- créer un thread;
- terminer l'exécution d'un thread.
- Cherhcer dans le manuel la documentation de chacune des fonctions que vous avez donné pour la question précedente.
Cherchez quelle option doit être passée à gcc afin de compiler un code utilisant la bibliothèque pthread
.
Le but de cet exercice est de de comprendre le comportement d'un programme multi-thread par rapport à un programme séquentiel.
Pour cela, nous allons créer un programme qui lancera deux threads.
Chaque thread appelera une fonction incrémentant une variable globale compteur
.
Puis, à la fin de l'exécution des threads, affiche la valeur du compteur.
- Ecrivez la fonction
incrementer
qui sera appelée à la création des threads pour augmenter la valeur du compteur. Le nombre d'incrémentation devra être passé en paramètre et la fonction ne renverra rien (enfin pas d'information en particulier). - Ecrivez le code de la fonction
main
afin de créer deux threads puis de les attendre et enfin d'afficher la valeur du compteur. Chaque thread devra appeler la fonction avec un nombre d'incrémentation de 1000. - Complétez le programme avec les bons includes et la variable globale afin que le code soit correcte.
- Compilez votre programme et tester le. Quelle valeur est affichée ? Est-ce normale ?
Pour pallier ce problème, nous allons protéger l'accès à la variable compteur par un mutex :
- Rajoutez une variable globale
mutex
que vous initialiserez de façon statique.
Il ne nous reste plus qu'à mettre une barrière avant d'incrémenter le compteur :
- Utilisez votre mutex pour protéger la mise à jour du compteur.
Dans cette exercice on se propose d'écrire un programme effectuant le découpage d'un calcul très long et d'affecter un thread par morceau issu de ce découpage.
Pour ce faire, nous allons créer une fonction calcul
dont le but est de calculer le résultat d'une somme d'un tableau contenue dans une variable globale.
Le code de base est le suivant :
#define TAILLE 100000 // Taille du tableau
#define NTHREAD 10 // Nombre de threads
int tableau[TAILLE];
void* somme(void *arg);
Notre but étant de découper le calcul de la somme en plusieur threads, nous allons devoir réaliser un découpage du code en plusieurs étapes. Commençons par initialiser le tableau.
- Ecrivez une fonction
initialiser
qui initialise le tableautableau
de telle manière à ce qu'il contienne les entiers consécutifs de 0 àTAILLE - 1
.
Nous allons à présent créer une structure afin de procéder au découpage de la tâche à exécuter. Cette structure sert à indiquer à chaque thread les données du tableau qu'il doit traité. L'idée est que ce découpage doit être tel que chaque thread traite des données contigues du tableau et traite le même nombre de case. Elle contient donc :
- Un indice de départ sous forme de nombre entier.
- Un nombre de case à traiter sous forme d'entier.
- Le tableau sous forme de pointeur d'entier.
- Codez la structure
arg_t
afin qu'elle contienne ces informations.
Maintenant que l'on a la structure pour effectuer le découpage, nous allons pouvoir créer la fonction somme.
-
Ecrivez la fonction
somme
. On supposera que l'argument passé en paramètre est une varaible de typearg_t
. -
Ecrivez le reste du programme afin de créer les threads et d'effectuer la somme, puis d'afficher le résultat dans le terminal.
Dans cette partie, on consid`ere deux tableaux de nombres flottants u et v, de taille n.
On souhaite calculer la somme
Le calcul doit être divisé en p
tâches indépendantes, chacune étant chargée de calculer une somme partielle de termes consécutifs et de taille similaire.
Les sommes partielles sont ensuite combinées pour produire la somme finale.
Pour ce faire, dans la fonction que vous êtes en train d'écrire pour chaque thread.
Vous devrez mettre à jour la somme globale. Vous devez également penser à protéger l'accès à cette variable.
Pour cet exercice, on pensera à traiter les cas ou p
ne divise pas la taille des tableaux u
et v
.