#include <pthread.h>
Lors de la compilation le paramétre -pthread
doit ajouté
gcc -Wall -Wextra -Werror -pthread test_thread.c
Dans le make file, pour la compilation de l'objet. ajouter -lpthread
<\p>
Cause l'erreur :r&eactue;f&eactue;rence ind&eactue;finie vers « pthread_create »
Cause l'erreur :r&eactue;f&eactue;rence ind&eactue;finie vers « pthread_join »
Il faut déclarer une variable de type pthread_t
par thread. Cette variable va permettre d'identifier les threads.
Deux solutions possible pthread_t p1, p2;
ou avec un malloc
pthread_t *array; array = malloc(2 * sizeof(pthread_t));
Ensuite il faut créer le thread, et traiter les erreurs de création.
if (pthread_create(&p1, NULL, body_thread, ¶m[i]) != 0) return(1);
ou
if (pthread_create(&array[i], NULL, body_thread, ¶m[i]) != 0) return(1);
Si aucun paramètre n'est requis par le thread, remplacer ¶m[i]
par NULL
.
Mise en attente du processus principal jusqu'a ce que tous les threads soient termines
Si une valeur devait être retournée par le thread, remplacer le NULL de pthread_join par cette valeur
while (i < pnb_threads) { pthread_join(array[i], NULL); i++; }
Ne pas oublier les free.
Dans le partie principale du programme il faut initialiser les mutex
pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL);
Et bien sûr les detruires une fois que tous les threads sont termines.
pthread_mutex_destroy(&mutex);
Dans le thread, entourer la partie a proteger par>
pthread_mutex_lock(¶m->mutex); GLOBAL_COMPTEUR++; printf("Thread: % ld - boucle:%d - Global compteur thread: %d\n",param->n_thread, i,GLOBAL_COMPTEUR); pthread_mutex_unlock(¶m->mutex);
Sans le mutex, il y a un risque d'apparition de duplicat (race condition) de valeur de GLOBAL_COMPTEUR. GLOBAL_COMPTEUR++ requiert en effet 3 opérations distinctes.
Ceci est visible dans le code assemblé si on effectue gcc -S -pthread pthread_mutex.c
.
movl GLOBAL_COMPTEUR(%rip), %eax addl $1, %eax movl %eax, GLOBAL_COMPTEUR(%rip)
L'entier du code se trouve dans /philo_dev/tools/pthread_mutec.c