Utiliser les sémaphores pour synchroniser des threads
Attention : il est conseillé de lire la documentation sur les threads avant cette page.
Description des sémaphores
La librairie de gestion des threads offre les fonctions ci-dessous pour créer et utiliser des sémaphores. Attention : ces sémaphores sont propres à un processus. Ils permettent de synchroniser plusieurs threads entre eux, mais ils ne peuvent synchroniser plusieurs processus. Pour réaliser cette synchronisation il faut se tourner vers les sémaphores système V basés sur les IPC (Inter Processus Communication).
- int sem_init(sem_t *semaphore, int pshared, unsigned int valeur)
- Création d'un sémaphore et préparation d'une valeur initiale.
- int sem_wait(sem_t * semaphore);
- Opération P sur un sémaphore.
- int sem_trywait(sem_t * semaphore);
- Version non bloquante de l'opération P sur un sémaphore.
- int sem_post(sem_t * semaphore);
- Opération V sur un sémaphore.
- int sem_getvalue(sem_t * semaphore, int * sval);
- Récupérer le compteur d'un sémaphore.
- int sem_destroy(sem_t * semaphore);
- Destruction d'un sémaphore.
Bien entendu, une aide plus complète peut être obtenue sur chaque fonction en utilisant le manuel UNIX :
man nom_de_la_fonction
Un exemple d'utilisation des sémaphores
Cet exemple illustre la mise en oeuvre d'une section critique (mutuelle exclusion) permettant d'éviter un mélange des affichages réalisés par les deux threads.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t mutex;
void* affichage (void* name)
{
int i, j;
for(i = 0; i < 20; i++) {
sem_wait(&mutex); /* prologue */
for(j=0; j<5; j++) printf("%s ",(char*)name);
sched_yield(); /* pour etre sur d'avoir des problemes */
for(j=0; j<5; j++) printf("%s ",(char*)name);
printf("\n ");
sem_post(&mutex); /* epilogue */
}
return NULL;
}
int main (void)
{
pthread_t filsA, filsB;
sem_init(&mutex, 0, 1);
if (pthread_create(&filsA, NULL, affichage, "AA")) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
if (pthread_create(&filsB, NULL, affichage, "BB")) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
if (pthread_join(filsA, NULL))
perror("pthread_join");
if (pthread_join(filsB, NULL))
perror("pthread_join");
printf("Fin du pere\n") ;
return (EXIT_SUCCESS);
}
Pour compiler et effectuer l'édition de liens vous devez utiliser la ligne suivante :
c'est la fin !