Reader Writer Problem

This commit is contained in:
MAO Dongyang 2023-04-05 14:32:43 +02:00
parent 9ee8f961b3
commit 2e796b1d83
No known key found for this signature in database
9 changed files with 823 additions and 0 deletions

View File

@ -0,0 +1,27 @@
CCOPTIONS=-g
CC=gcc $(CCOPTIONS)
all : lecteurs-redacteurs-mutex lecteurs-redacteurs-moniteur
clean :
rm lecteurs-redacteurs-mutex lecteurs-redacteurs-moniteur semaphore-moniteur.o tprintf.o
lecteurs-redacteurs-mutex : lecteurs-redacteurs-mutex.c tprintf.o
$(CC) -o lecteurs-redacteurs-mutex lecteurs-redacteurs-mutex.c tprintf.o -lpthread
lecteurs-redacteurs-moniteur : lecteurs-redacteurs-moniteur.c tprintf.o
$(CC) -o lecteurs-redacteurs-moniteur lecteurs-redacteurs-moniteur.c tprintf.o -lpthread
semaphore-moniteur.o : semaphore-moniteur.c semaphore-moniteur.h
$(CC) -c semaphore-moniteur.c
tprintf.o : tprintf.c tprintf.h
$(CC) -c tprintf.c

View File

@ -0,0 +1,213 @@
**********************************
TP 5 - Moniteurs et semaphores de comptage en pthread
Partie 2 : Problème des lecteurs/redacteurs
Duree: 3h
**********************************
**********************************
Resolution du probleme des lecteurs redacteurs avec les pthreads
- Partie 2.1: avec des semaphores de comptage uniquement
- Partie 2.2: avec des semaphores mutex uniquement
- Partie 2.3: avec des moniteurs uniquement
**********************************
Contenu:
* lecteurs-redacteurs-mutex.c :
Le fichier d'implementation des lecteurs redacteurs pour semaphores mutex uniquement (ou semaphores de comptage) qui contient:
lecteur() : fonction principale des threads lecteurs
redacteurs () : fonction principale des threads redacteurs
main() : fonction principale du processus (initialisation, demarrage/terminaison des threads, finalisation)
* lecteurs-redacteurs-moniteur.c :
Le fichier d'implementation des lecteurs redacteurs pour les moniteurs uniquement (mutex et conditions) qui contient:
m_prologue_lecteur() et m_epilogue_lecteur(): les points d'entree du moniteur pour les lecteurs
m_prologue_redacteur() et m_epilogue_redacteur(): les points d'entree du moniteur pour les redacteurs
lecteur() : fonction principale des threads lecteurs
redacteurs () : fonction principale des threads redacteurs
main() : fonction principale du processus (initialisation, demarrage/terminaison des threads, finalisation)
* semaphore-moniteur.h, semaphore-moniteur.c :
Les fichiers d'implementation des semaphores de comptage avec les moniteurs pthreads (à utiliser dans la partie 2.1)
type_semaphore ;
init_semaphore(); destroy_semaphore();
P_semaphore(); V_semaphore();
* tprinf.h, tprinf.c :
Les fichiers d'implementation d'un utilitaire tprinf() et tfprintf()
printf() prefixe par "seconds:microsecondes:pid: "), a utiliser pour dater tous les messages
* macros-thread.h :
un fichier d'utiliaires (macros C) bien pratiques pour simplifier l'utilisation
des mutex et des conditions pthread (pour les parties mutex 2.2 et moniteur 2.3))
* makefile :
le fichier de construction automatique
make all : construit tous les executables
make clean : efface tous les fichiers compiles
*************************************
*************************************
Sujet de TP :
*************************************
*************************************
*************************************
Partie 2.1 : solution a base de semaphores de comptage
fichier: lecteurs-redacteurs-mutex.c
*************************************
1) commencez par analyser en detail le contenu des differents fichiers
2) compilez le fichier lecteurs-redacteurs-mutex.c avec le makefile et essayer le programme sans synchronisation. Que ce passe-t-il ?
3) A l'aide de semaphores de comptage , resolvez le probleme des lecteurs redacteurs.
Proposez 3 solutions differentes: equite, priorite lecteurs, priorite redacteurs
Validez les solutions a l'aide de l'outil JPNS, construisez les reseaux de petri correspondant, et validez-les par simulation.
4) Implementation des solutions (un fichier different par solution)
Implementez les solutions avec le module semaphores de comptage propose dans semaphore-moniteur.h, semaphore-moniteur.c.
Encadrez chaque operation P() et V() sur les semaphores d'un messsage tprint() afin de tracer/logger l'instant des operations
Modifiez la chaine de lancement des processus lecteurs et redacteurs (macros NBTHREADS et STARTING_CHAIN)
utilisez un debogueur/devermineur supportant le parallelisme des threads (gdb, ddd, ...).
5) Faites la preuve du bon fonctionnement de la solution priorite redacteur:
- en analysant les messages encadrant les operation P() et V()
- en utilisant les commandes unix ps, top avec les options adaptees aux threads
- en dessinant le chronogramme d'utilisation des operations P() et V() des semaphores de comptage pour l'ensemble des threads lecteurs/redacteurs actives.
*************************************
Partie 2.2 : solution a base de semaphores mutex
fichier: lecteurs-redacteurs-mutex.c
*************************************
3) A l'aide de semaphores mutex pthreads (verrous ou semaphores binaires), resolvez le probleme des lecteurs redacteurs.
Proposez 3 solutions differentes: equite, priorite lecteurs, priorite redacteurs
Validez les solutions a l'aide de l'outil JPNS, construisez les reseaux de petri correspondant, et validez-les par simulation.
4) Implementation des solutions (un fichier different par solution)
Implementez les solutions avec les mutex pthread (ptread_mutex_* : ptrhread_mutex_t, ptrhread_mutex_init(), ptrhread_mutex_destroy(), ptrhread_mutex_lock(), ptrhread_mutex_unlock() )
Vous pouvez aussi utiliser les macros du module macros-thread.h : INIT_MUTEX(), DESTROY_MUTEX(), P_MUTEX(), V__MUTEX()
Encadrez chaque operation P() et V() sur les mutex d'un messsage tprint() afin de tracer/logger l'instant des operations
Modifiez la chaine de lancement des processus lecteurs et redacteurs (macros NBTHREADS et STARTING_CHAIN)
utilisez un debogueur/devermineur supportant le parallelisme des threads (gdb, ddd, ...).
5) Faites la preuve du bon fonctionnement de la solution priorite redacteur:
- en analysant les messages encadrant les operation P() et V()
- en utilisant les commandes unix ps, top avec les options adaptees aux threads
- en dessinant le chronogramme d'utilisation des operations P() et V() sur les mutex pour l'ensemble des threads lecteurs/redacteurs actives.
*************************************
Partie 2.3 : solution a base de moniteurs (mutex et conditions)
fichier: lecteurs-redacteurs-moniteur.c
*************************************
1) commencez par analyser en detail le contenu des differents fichiers
2) compilez le fichier lecteurs-redacteurs-mutex.c avec le makefile et essayer le programme sans synchronisation. Que ce passe-t-il ?
3) A l'aide des outils moniteur des pthreads (mutex et conditions), resolvez le probleme des lecteurs redacteurs dans lecteurs-redacteurs-moniteur.c.
proposez 3 solutions differentes: equite, priorite lecteurs, priorite redacteurs.
4) Implementation des solutions (un fichier different par solution)
Implementez les solutions avec les mutex pthread (ptread_mutex_* : ... ) et les conditions pthread (ptrhread_cond_t, ptrhread_cond_init(), ptrhread_cond_destroy(), ptrhread_cond_wait(), ptrhread_cond_signal() )
Vous pouvez aussi utiliser les macros du module macros-thread.h : INIT_MUTEX(), DESTROY_MUTEX(), P_MUTEX(), V__MUTEX(), et INIT_COND(), DESTROY_COND(), WAIT_COND(), SIGNAL__COND()
Encadrez chaque operation P(), V(), WAIT(), SIGNAL() sur les mutex et les conditions d'un messsage tprint() afin de tracer/logger l'instant des operations
Modifiez la chaine de lancement des processus lecteurs et redacteurs (macros NBTHREADS et STARTING_CHAIN)
utilisez un debogueur/devermineur supportant le parallelisme des threads (gdb, ddd, ...).
5) Faites la preuve du bon fonctionnement de la solution priorite redacteur:
- en analysant les messages encadrant les operation P(), V(), WAIT(), SIGNAL()
- en utilisant les commandes unix ps, top avec les options adaptees aux threads
- en dessinant le chronogramme d'utilisation des operations P(), V(), WAIT(), SIGNAL() sur les mutex et les conditions pour l'ensemble des threads lecteurs/redacteurs actives.
*************************************
ANNEXES
*************************************
1) Déboguer les pthreads avec gdb
Pour pouvoir controller les threads indépendamment, il suffit d'entrer la séquence de commandes suivante dans gdb:
# Enable the async interface.
set target-async 1
# If using the CLI, pagination breaks non-stop.
set pagination off
# Finally, turn it on!
set non-stop on
Entrer ces commandes dans le fichier ~/.gdbinit pour qu'elles soient prises en compte automatiquement.
Pour les détails, voir: Non-Stop Mode <https://sourceware.org/gdb/current/onlinedocs/gdb/Non_002dStop-Mode.html>
2) Tutoriel débogueur gdb
voir : Débuggage avec gdb <https://doc.ubuntu-fr.org/gdb>
et Debugging Programs with Multiple Threads <https://sourceware.org/gdb/current/onlinedocs/gdb/Threads.html#Threads>
commande raccourci effet
run r lance le programme (s'arrête au prochain point d'arrêt)
continue c relance le programme (s'arrête au prochain point d'arrêt)
break xx b xx place un point d'arrêt à la ligne ou à la fonction xx
info breakpoints info breakpoints liste les points d'arrêts
delete d efface les points d'arrêts
next n exécute une instruction (ne rentre pas dans les fonctions)
step s exécute une instruction (rentre potentiellement dans les fonctions)
finish f exécute les instructions jusqu'à la sortie de la fonction
until xx u xx exécute les instructions jusqu'à la ligne xx
watch var w var surveille la variable var
print expr p expr interprète et affiche expr
info threads liste les threads en cours (* devant le thread courant)
thread thread-id thread id devient le thread courant
3) Débogueur et IDE
débogueurs seuls : gdb, DDD, Kdb, ...
environnment de developpement (IDE) : eclipse, Kblocks, KDevelop, Code::Blocks, ...
4) Pour deboguer les pthreads en linux dans netbeans. (préférer eclipse)
Ceci peut être fait dans netbeans 7.0. Pour installer c/c++ dans netbeans, suivre les étapes suivantes:
- menu "tools/plugins"
- dans settings parametrer le proxy "proxy settings" cache.etu.univ-nantes.fr:3128
- dans settings, activez les sources "Certified Plugins, Netbeans Distribution, et Plugin Portal
- dans "available plugins" rafraichir le catalogue (update ou refresh), puis installer c/c++
Il faut aussi mettre à jour netbeans:
- dans "update" rafraichir le catalogue (update ou refresh), puis bouton update
La console gdb est accessible dans menu: "window/debugging/debugger console"
La fenêtre de contrôle des threads dans : "window/debugging/threads"
Entrer les commandes de la 1ere partie dans le fichier ~/.gdbinit pour qu'elles soient prises en compte automatiquement.

View File

@ -0,0 +1,229 @@
/*
* Problème des Lecteurs rédacteurs
* bibliothèque pthread
* Solution avec moniteurs (mutex et conditions)
*
*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "macros-thread.h"
#include "tprintf.h"
/* Modifier ici la chaine de lancement des threads */
#define NBTHREADS 6
#define STARTING_CHAIN {"w1","r1", "r2", "r3", "w2", "r4"}
/* Notions Globales */
/* Définition du moniteur: variables d'état, mutex, conditions */
/* ----------------------------------------------------------- */
int nbLecteurs=0; /* Ressource Critique */
int nbRedacteurs=0; /* Ressource Critique */
/* -- A COMPLETER -- */
/* declarer mutex et conditions pour le moniteur */
/* Points d'entrée du moniteur proteges par E.M.*/
void m_prologue_lecteur(char *);
void m_epilogue_lecteur(char *);
void m_prologue_redacteur(char *);
void m_epilogue_redacteur(char *);
/* Fonctions du moniteur */
void m_prologue_lecteur(char * nom) {
/* -- A COMPLETER -- */
/* Section à mettre en Exclusion Mutuelle */
/* par ex:
tprintf("producteur %s demande P(mutex)...\n", nom);
P_MUTEX(mutex);
tprintf("producteur %s obtient P(mutex)...\n", nom);
*/
/* code en E.M. sur mutex */
/* -- A COMPLETER -- */
/* gerer la synchronisation lecteurs/redacteurs */
nbLecteurs ++;
/* fin d'E.M. */
/* -- A COMPLETER -- */
/* Mettre fin à la section en Exclusion Mutuelle */
}
void m_epilogue_lecteur(char * nom) {
/* -- A COMPLETER -- */
/* Section à mettre en Exclusion Mutuelle */
/* code en E.M. sur mutex */
/* -- A COMPLETER -- */
/* gerer la synchronisation lecteurs/redacteurs */
nbLecteurs --;
/* fin d'E.M. */
/* -- A COMPLETER -- */
/* Mettre fin à la section en Exclusion Mutuelle */
}
void m_prologue_redacteur(char * nom) {
/* -- A COMPLETER -- */
/* Section à mettre en Exclusion Mutuelle */
/* code en E.M. sur mutex */
/* -- A COMPLETER -- */
/* gerer la synchronisation lecteurs/redacteurs */
nbRedacteurs=1;
/* fin d'E.M. */
/* -- A COMPLETER -- */
/* Mettre fin à la section en Exclusion Mutuelle */
}
void m_epilogue_redacteur(char * nom) {
/* -- A COMPLETER -- */
/* Section à mettre en Exclusion Mutuelle */
/* code en E.M. sur mutex */
/* -- A COMPLETER -- */
/* gerer la synchronisation lecteurs/redacteurs */
nbRedacteurs=0;
/* fin d'E.M. */
/* -- A COMPLETER -- */
/* Mettre fin à la section en Exclusion Mutuelle */
}
/* fin de definition du moniteur */
/* ----------------------------- */
/* Fonction principales des threads "redacteur" */
void * redacteur(void * arg) {
char * nom = *(char **)arg;
tprintf("debut thread redacteur %s\n", nom);
m_prologue_redacteur(nom);
tprintf("%s ecrit...\n", nom);
sleep(5+rand()%6);
tprintf("%s etat du tampon partage: nbLecteurs=%i\n", nom, nbLecteurs);
tprintf("%s a fini d ecrire...\n", nom);
m_epilogue_redacteur(nom);
tprintf("fin thread redacteur %s\n", nom);
pthread_exit(EXIT_SUCCESS);
}
/* Fonction principales des threads "lecteur" */
void * lecteur(void * arg) {
char * nom = *(char **)arg;
tprintf("debut thread lecteur %s\n", nom);
m_prologue_lecteur(nom);
tprintf("%s lit...\n", nom);
sleep(1+rand()%3);
tprintf("%s a fini de lire...\n", nom);
m_epilogue_lecteur(nom);
tprintf("fin thread lecteur %s\n", nom);
pthread_exit(EXIT_SUCCESS);
}
/* Affichage de la chaine de lancement des threads */
char * chaine_lancement(char * nomsThreads[], char * sep) {
static char starting_chain[3*NBTHREADS+1]="";
strcat(starting_chain, nomsThreads[0]) ;
for ( int i=1; i<NBTHREADS; i++ ) {
strcat(starting_chain, sep) ;
strcat(starting_chain, nomsThreads[i]) ;
}
return starting_chain;
}
/* Fonction principales de demarrage et de creation des threads */
int main () {
/* Changer cette chaine de lancement des processus pour tester d'autres configurations */
char * nomsThreads[NBTHREADS] = STARTING_CHAIN;
pthread_t threads[NBTHREADS];
void * (* thread_main) (void *);
int i, errcode;
/* -- A COMPLETER -- */
/* initialiser les mutex et conditions du moniteur */
nbLecteurs=0;
nbRedacteurs=0;
/* Affichage de la chaine de lancement des threads */
tprintf("Chaine de lancement des threads : %s \n", chaine_lancement(nomsThreads, " ") );
for ( i=0; i<NBTHREADS; i++ ){
if ( nomsThreads[i][0]=='r' ) {
thread_main = lecteur;
} else if ( nomsThreads[i][0]=='w' ) {
thread_main = redacteur;
}
errcode=pthread_create (&threads[i], NULL, thread_main, &nomsThreads[i]);
if ( errcode != 0 ) {
fprintf(stderr, "Erreur de creation du thread %s\n", nomsThreads[i]);
}
}
for (i=0; i<NBTHREADS; i++) {
errcode=pthread_join (threads[i], NULL);
if (errcode) {
fprintf(stderr, "erreur pthread_join pour le thread %s\n", nomsThreads[i]);
exit(EXIT_FAILURE);
}
}
/* -- A COMPLETER -- */
/* Detruire les mutex et conditions du moniteur */
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,128 @@
/*
* Problème des Lecteurs rédacteurs
* bibliothèque pthread
* Solution avec semaphores mutex uniquement
*
*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "macros-thread.h"
#include "tprintf.h"
/* Modifier ici la chaine de lancement des threads */
#define NBTHREADS 6
#define STARTING_CHAIN {"w1","r1", "r2", "r3", "w2", "r4"}
/* Notions Globales */
#define NBTHREADS 6
int nbLecteurs = 0;
/* -- A COMPLETER -- */
/* declarer les semaphores mutex */
/* Fonction principales des threads "redacteur" */
void * redacteur(void * arg) {
char * nom = *(char **)arg;
tprintf("debut thread redacteur %s\n", nom);
/* -- A COMPLETER -- */
/* gerer la synchronisation lecteurs/redacteurs */
tprintf("%s ecrit...\n", nom);
sleep(5+rand()%6);
tprintf("%s : nbLecteurs=%i\n", nom, nbLecteurs);
tprintf("%s a fini d ecrire...\n", nom);
/* -- A COMPLETER -- */
/* gerer la synchronisation lecteurs/redacteurs */
tprintf("fin thread redacteur %s\n", nom);
pthread_exit(EXIT_SUCCESS);
}
/* Fonction principales des threads "lecteur" */
void * lecteur(void * arg) {
char * nom = *(char **)arg;
tprintf("debut thread lecteur %s\n", nom);
/* -- A COMPLETER -- */
/* gerer la synchronisation lecteurs/redacteurs */
tprintf("%s lit...\n", nom);
sleep(1+rand()%3);
tprintf("%s a fini de lire...\n", nom);
/* -- A COMPLETER -- */
/* gerer la synchronisation lecteurs/redacteurs */
tprintf("fin thread lecteur %s\n", nom);
pthread_exit(EXIT_SUCCESS);
}
/* Affichage de la chaine de lancement des threads */
char * chaine_lancement(char * nomsThreads[], char * sep) {
static char starting_chain[3*NBTHREADS+1]="";
strcat(starting_chain, nomsThreads[0]) ;
for ( int i=1; i<NBTHREADS; i++ ) {
strcat(starting_chain, sep) ;
strcat(starting_chain, nomsThreads[i]) ;
}
return starting_chain;
}
/* Fonction principales de demarrage et de creation des threads */
int main () {
/* Changer cette chaine de lancement des processus pour tester d'autres configurations */
char * nomsThreads[NBTHREADS] = STARTING_CHAIN;
pthread_t threads[NBTHREADS];
void * (* thread_main) (void *);
int i, errcode;
/* -- A COMPLETER -- */
/* initialiser les semaphores mutex */
/* Affichage de la chaine de lancement des threads */
tprintf("Chaine de lancement des threads : %s \n", chaine_lancement(nomsThreads, " ") );
/* Creation des threads lecteurs et redacteurs */
for ( i=0; i<NBTHREADS; i++ ){
if ( nomsThreads[i][0]=='w' ) {
thread_main = redacteur;
} else if ( nomsThreads[i][0]=='r' ) {
thread_main = lecteur;
}
errcode=pthread_create (&threads[i], NULL, thread_main, &nomsThreads[i]);
if ( errcode != 0 ) {
fprintf(stderr, "Erreur de creation du thread %s\n", nomsThreads[i]);
}
}
/* Attente de terminaison de tous les threads */
for (i=0; i<NBTHREADS; i++) {
errcode=pthread_join (threads[i], NULL);
if (errcode) {
fprintf(stderr, "erreur pthread_join pour le thread %s\n", nomsThreads[i]);
exit(EXIT_FAILURE);
}
}
/* -- A COMPLETER -- */
/* Detruire les semaphores mutex */
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,31 @@
/* Ensemble de macros bien pratiques pour les moniteurs pthreads */
#ifndef _MACROS_THREADS_H_
#define _MACROS_THREADS_H_
/* Mutex */
#define INIT_MUTEX(unMutex) if (pthread_mutex_init(&(unMutex), NULL)) { perror("pthread_mutex_init (&(unMutex), NULL)"); pthread_exit(NULL);}
#define P_MUTEX(unMutex) if (pthread_mutex_lock(&(unMutex))) { perror("pthread_mutex_lock(&(unMutex))"); pthread_exit(NULL);}
#define V_MUTEX(unMutex) if (pthread_mutex_unlock(&(unMutex))) { perror("pthread_mutex_unlock(&(unMutex))"); pthread_exit(NULL);}
#define DESTROY_MUTEX(unMutex) if (pthread_mutex_destroy(&(unMutex))) { perror("pthread_mutex_destroy(&(unMutex))"); pthread_exit(NULL);}
/* Conditions */
#define INIT_COND(uneCondition) if (pthread_cond_init(&(uneCondition), NULL)) { perror("pthread_cond_init(&(uneCondition), NULL)"); pthread_exit(NULL);}
#define WAIT_COND(uneCondition,unMutex) if (pthread_cond_wait(&(uneCondition), &(unMutex))) { perror("pthread_cond_wait(&(uneCondition), &(unMutex))"); pthread_exit(NULL);}
#define SIGNAL_COND(uneCondition) if (pthread_cond_signal(&(uneCondition))) { perror("pthread_cond_signal(&(uneCondition))"); pthread_exit(NULL);}
#define DESTROY_COND(uneCondition) if (pthread_cond_destroy(&(uneCondition))) { perror("pthread_cond_destroy(&(uneCondition))"); pthread_exit(NULL);}
#endif

View File

@ -0,0 +1,103 @@
/*
* Implementation d'un sémaphore de comptage par moniteurs
* bibliothèque pthread
* moniteurs = semaphores binaires (mutex) + conditions
*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "tprintf.h"
#include "macros-thread.h"
#include "semaphore-moniteur.h"
/* Définition du moniteur */
/* ---------------------- */
/* Points d'entrée */
/* Fonctions du moniteur */
/* seulement 2 fonctions en exclusion mutuelle : P_semaphore() et V_semaphore() */
/* Attention, les autres fonction sne sont pas protegees */
void init_semaphore(type_semaphore * sem, int val){
/* implementer l'initialisation de tous les champs
de l'enregistrement type-semaphore: mutex, attenteFifo, nbAttente, value
utiliser INIT_MUTEX, et INIT_COND
*/
INIT_MUTEX(sem->mutex);
INIT_COND(sem->attenteFifo);
sem->nbAttente=0;
sem->value=val;
return;
}
void P_semaphore(type_semaphore * sem){
/* implementer l'operateur semaphore P(sem) en exclusion mutuelle
modifie les champs de l'enregistrement type-semaphore: nbAttente, value
utiliser P_MUTEX, V_MUTEX et WAIT_COND
*/
P_MUTEX(sem->mutex);
sem->value--;
if ( sem->value < 0 ) {
sem->nbAttente++;
WAIT_COND(sem->attenteFifo,sem->mutex);
sem->nbAttente--;
}
V_MUTEX(sem->mutex);
return;
}
void V_semaphore(type_semaphore * sem){
/* implementer l'operateur semaphore V(sem) en exclusion mutuelle
modifie les champs de l'enregistrement type-semaphore: value
utiliser P_MUTEX, V_MUTEX et SIGNAL_COND
*/
P_MUTEX(sem->mutex);
sem->value++;
if ( sem->value <= 0 ) {
SIGNAL_COND(sem->attenteFifo);
}
V_MUTEX(sem->mutex);
return;
}
void destroy_semaphore(type_semaphore * sem){
/* implementer la destruction du semaphore
modifie les champs de l'enregistrement type-semaphore: nbAttente, value
*/
DESTROY_MUTEX(sem->mutex);
DESTROY_COND(sem->attenteFifo);
sem->nbAttente=0;
sem->value=0;
return;
}
int value_semaphore(type_semaphore * sem){
/* implementer la lecture non protegee de la valeur du semaphore: champs value */
return sem->value;
}
int estVideFifo_semaphore(type_semaphore * sem){
/* implementer l'acces au nombre de processus en attente en liste Fifo semaphore: champs nbAttente */
return sem->nbAttente==0;
}

View File

@ -0,0 +1,33 @@
/*
* Implementation de semaphore de comptage par moniteur
* bibliothèque pthread
* Moniteur = semaphores binaires(mutex) + conditions
*
*/
#ifndef _SEM_
#define _SEM_
#include <pthread.h>
/* Notions Globales */
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t attenteFifo;
int nbAttente;
int value;
} type_semaphore;
void init_semaphore(type_semaphore * sem,int val);
void P_semaphore(type_semaphore * sem);
void V_semaphore(type_semaphore * sem);
void destroy_semaphore(type_semaphore * sem);
int value_semaphore(type_semaphore * sem);
int estVideFifo_semaphore(type_semaphore * sem);
#endif

View File

@ -0,0 +1,48 @@
/* Utilitaire printf estampille : a reutiliser ...
print et fprintf prefixes par "seconds:microsecondes:pid: " ou "seconds:microsecondes:pid:tid: "
*/
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <stdarg.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include "tprintf.h"
/* printf estampille : a reutiliser ... */
int tprintf(const char * message, ... ) {
va_list liste;
char chaine [1000];
struct timeval t;
int pid = getpid();
int tid = (int) syscall(SYS_gettid);
va_start(liste, message);
gettimeofday( &t, NULL);
vsprintf(chaine, message, liste);
if ( pid == tid )
return printf("%ld:%ld:%i: %s", t.tv_sec, t.tv_usec, pid, chaine );
else
return printf("%ld:%ld:%i:%i %s", t.tv_sec, t.tv_usec, pid, tid, chaine );
}
int tfprintf(FILE * stream, const char * message, ... ) {
va_list liste;
char chaine [1000];
struct timeval t;
int pid = getpid();
int tid = (int) syscall(SYS_gettid);
va_start(liste, message);
gettimeofday( &t, NULL);
vsprintf(chaine, message, liste);
if ( pid == tid )
return fprintf(stream, "%ld:%ld:%i: %s", t.tv_sec, t.tv_usec, pid, chaine );
else
return fprintf(stream, "%ld:%ld:%i:%i %s", t.tv_sec, t.tv_usec, pid, tid, chaine );
}

View File

@ -0,0 +1,11 @@
/* Utilitaire printf estampille : a reutiliser ...
print et fprintf prefixes par "seconds:microsecondes:pid: " ou "seconds:microsecondes:pid:tid: "
*/
#include <stdarg.h>
/* printf estampille : a reutiliser ... */
int tprintf( const char *, ... );
int tfprintf(FILE * stream, const char * message, ... );