langage_C/System2/RW_problem/lecteurs-redacteurs-mutex.c

129 lines
3.1 KiB
C

/*
* 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);
}