Ce programme peut servir à comprendre comment fonctionne les taches unix, et comment protéger les variables globales partagées entre taches grace à des semaphores.
Source / Exemple :
/* ---------------------------------------------------------------------------
- Programme utilisant des threads (taches)
- Auteurs : fgazier
- Création : 15/10/03
- Entrées : --
- Sorties : écran
- Avancement : OK et testé
- -------------------------------------------------------------------------*/
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
int globale = 0;
typedef struct {
int valAdd;
sem_t * sem;
} Sem_et_int;
void * malloc (size_t size);
void free (void * ptr);
void * addNumtachVarglob(void *pointStruc);
/* ---------------------------------------------------------------------------
- Nom de la fonction : Main
- But : Créer dix taches (thread) utilisant une variable globale et protège
- l'accès en parrallèle des taches sur la variable globale grace à
- l'utilisation d'un Sémaphore.
- -------------------------------------------------------------------------*/
int main(void)
{
int i;
sem_t semaphore_i;
Sem_et_int * ind[10];
pthread_t thr[10];
i = 1;
if (sem_init(&(semaphore_i), 0, 1) == -1)
{
printf("Erreur à la création d'un sémaphore.\n");
return 0;
}
while (i != 11)
{
ind[i]=malloc(sizeof(Sem_et_int));
(*ind[i]).valAdd = i;
(*ind[i]).sem = &semaphore_i;
pthread_create(&thr[i], NULL, addNumtachVarglob,(void *) ind[i]);
i++;
}
sleep(11);
printf("La variable globale est égale à %d\n", globale);
if (sem_destroy(&(semaphore_i)) == -1)
{
printf("Erreur à la destruction du sémaphore.\n");
return 0;
}
return 0;
}
/* ---------------------------------------------------------------------------
- Nom de la fonction : addNumtachVarglob
- But : Cette fonction est exécutée par toutes les taches. Elle doit ajouter
- des valeurs qu'on lui transmet en paramètre, à la variable globale,
- tout en protégeant les sections critiques par des sémaphores.
- Paramètres entrées/sortie : La fonction reçoit en entrée un pointeur sur
- "n'importe quoi = VOID", et ne renvoit rien en sortie.
- Précondition : La structure sur laquelle pointe le pointeur sur Void,
- doit etre "correctement" instanciée.
- -------------------------------------------------------------------------*/
void *addNumtachVarglob(void *pointStruc)
{
Sem_et_int *point;
point = pointStruc;
printf("Tache %d rentre dans le semaphore.\n", (*point).valAdd);
/* Verrouillage des variables globales */
sem_wait((*point).sem);
{
int locale = globale;
sleep(1);
printf("Var glob = : %d \n", (*point).valAdd);
locale += (*point).valAdd;
globale = locale;
}
/* Deverrouillage des variables globales */
sem_post((*point).sem);
printf("Tache %d est sortie du semaphore\n", (*point).valAdd);
free(point);
return NULL;
}
Conclusion :
Aucun bug connus (vérification ayant été minutieuse)