Threads & Mutex

Sources d'information

Librairie(s) requise(s)

#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 »

Comment ça marche les threads

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, &param[i]) != 0)
            return(1);

ou

if (pthread_create(&array[i], NULL, body_thread, &param[i]) != 0)
            return(1);

Si aucun paramètre n'est requis par le thread, remplacer &param[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.

Comment ça marche les mutex

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

retour


© 2022, vroch
Revisé le : 07 mai 2022
URL : http://vroch.ch/vr_tech_010.html
Main : http://vroch.ch