bonjour
je doit rendre le probleme 1 prducteur N consomateurs la semaine prochaine mais j'ai un probleme de code je vois le probleme est ce que vous pouvez m'aider
merci bien
/***************************************************************************************************************************/
/* définition des bibliothèques */
#define _REENTRANT
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#define TAILLE_FILE_ATTENTE 5 /* Taille de la file d'attente */
/* Déclaration Etat production / consommation */
int etatprod=1; /*1 si en production, 0 sinon */
int etatcons=1; /*1 si en consommation, 0 sinon */
int arretprod=0; /* 1 si on souhaite arreter la production, 0 sinon */
int arretcons=0; /* 1 si on souhaite arreter la consommation, 0 sinon */
/* Déclaration du terminal */
FILE * terminal;
/* Variables globales */
int nbprod;
int nbcons;
/* déclaration des variables conditionnelles */
pthread_cond_t cond_ecriture = PTHREAD_COND_INITIALIZER;;
pthread_cond_t cond_lecture = PTHREAD_COND_INITIALIZER;;
/* Déclaration File d'attente */
int nbplalibres=TAILLE_FILE_ATTENTE;
char * file_attente[TAILLE_FILE_ATTENTE];
int positionlecture=0;
int positionecriture=0;
/* Tableau des identifiants des threads */
pthread_t* t_conso;
pthread_t* t_prod;
pthread_t t_supervision;
/* Déclaration des mutex lecture, ecriture , producteurs et consommateurs */
pthread_mutex_t mutex_ecriture = PTHREAD_MUTEX_INITIALIZER;/* mutex permettant d'ecrire dans la file */
pthread_mutex_t mutex_lecture = PTHREAD_MUTEX_INITIALIZER;/* mutex permettant de lire la file */
pthread_mutex_t mutex_case_libre = PTHREAD_MUTEX_INITIALIZER;
/* Fonction gérant les erreurs */
void ctrlArg (int argc, char **argv, int nbArg)
/* controle du nombre d'argument d'un programme */
{
int i;
if (argc!=nbArg+1) /* si le nombre d'argument est incorrect */
{
fprintf(stderr,"Nombre d'arguments incorrect\nUsage : %s",argv[0]);
for(i=1;i<=nbArg;i++)
fprintf(stderr," argument%d",i);
fprintf(stderr,"\n");
exit(1);
}
}
void exitOnErrSyst (char *nomFonction, char *texte)
/* Gestion d'une erreur système */
{
fprintf(stderr,"ERREUR fonction %s - %s",nomFonction,texte);
perror("");
exit(1);
}
/***************************************************************************************************************************/
/* Thread du producteur */
void *producteur(void *arg)
{
int r=0;
char tampon[5][10];
strcpy(tampon[0],"Banane");
strcpy(tampon[1],"Ananas");
strcpy(tampon[2],"Pomme");
strcpy(tampon[3],"Cidre");
strcpy(tampon[4],"raisin");
time_t t;
char * date;
int idpro=(int)arg;
/* On attend les ordres du superviseur */
while(1)
{
/* Tant qu'il n'y a pas de production ou si on souhaite arreter la production */
while( (etatprod==0) || (nbplalibres==0) || (arretprod ==1) )
{
if(arretprod==1) /* si on souhaite arreter la production */
{
pthread_exit(NULL);
}
if(etatprod==0) /* si il n'y a pas de production */
{
fprintf(stdout,"\n\nSupervision : producteur %d en sommeil\n",idpro);
if( (pthread_cond_wait(&cond_ecriture,&mutex_ecriture)) != 0)
{
fprintf(stdout,"\n\nAttente producteur");
}
}
}
sleep(1); /* Attende de production : 1sc entre 2 productions */
file_attente[positionecriture]=(char*)malloc(sizeof(char)*(strlen(tampon[r])+1));
if( (pthread_mutex_lock(&mutex_case_libre)) != 0)
{
exitOnErrSyst("pthread_mutex_lock","blocage case libre");
}
nbplalibres--;
if( (pthread_mutex_unlock(&mutex_case_libre)) != 0)
{
exitOnErrSyst("pthread_mutex_unlock","libération case libre");
}
if( (pthread_mutex_lock(&mutex_ecriture)) != 0)
{
exitOnErrSyst("pthread_mutex_lock","blocage Mutex ecriture");
}
/* si il y a de la place, on ecrit un message dans la file et on récupère le temps*/
r=(r+1)%5;
file_attente[positionecriture]=tampon[r];
t=time(NULL);
date=ctime(&t);
/* Ecriture dans un fichier du message producteur */
fprintf(stdout,"\n\n%s Producteur numéro %d écriture case %d produit %s\n",date,idpro,positionecriture,file_attente[positionecriture]);
positionecriture = (positionecriture+1)%TAILLE_FILE_ATTENTE;
if( (pthread_mutex_unlock(&mutex_ecriture)) != 0)
{
exitOnErrSyst("pthread_mutex_unlock","libération Ecriture file");
}
/* On signale qu'il y a quelque chose à lire dans cette case car la case a été écrite */
if( (pthread_cond_signal(&cond_lecture)) != 0)
{
fprintf(stdout,"\n\nErreur Variable conditionnelle lecture");
exit(1);
}
}
}
/***************************************************************************************************************************/
/* Thread du consommateur */
void *consommateur(void *arg)
{
time_t t;
char * date;
int idcons=(int)arg;
/* On attend les ordres du superviseur */
while(1)
{
/* Tant qu'il n'y a pas de consommation ou si on souhaite arreter la consommation */
while( (etatcons==0) || (arretcons ==1) || (nbplalibres==TAILLE_FILE_ATTENTE) )
{
if(arretcons==1) /* si on souhaite arreter la consommation */
{
pthread_exit(NULL);
}
if(etatcons==0) /* si il n'y a pas de consommation */
{
fprintf(stdout,"\n\nSupervision : consommateur %d en sommeil\n",idcons);
if( (pthread_cond_wait(&cond_lecture,&mutex_lecture)) != 0)
{
fprintf(stdout,"\n\nAttente consommateur");
}
}
}
sleep(2); /* Attende de consommation : 2sc entre 2 consommations */
if( (pthread_mutex_lock(&mutex_case_libre)) != 0)
{
exitOnErrSyst("pthread_mutex_lock","blocage case libre");
}
nbplalibres++;
if( (pthread_mutex_unlock(&mutex_case_libre)) != 0)
{
exitOnErrSyst("pthread_mutex_unlock","libération case libre");
}
if( ( pthread_mutex_lock(&mutex_lecture)) != 0)
{
exitOnErrSyst("pthread_mutex_lock","blocage Mutex ecriture");
}
t=time(NULL);
date=ctime(&t);
/* Ecriture dans un fichier du message consommateur */
fprintf(stdout,"\n\n%s Consommateur numéro %d lecture case %d j'aime %s\n",date,idcons,positionlecture,file_attente[positionlecture]);
free(file_attente[positionlecture]);
positionlecture=(positionlecture + 1)%TAILLE_FILE_ATTENTE;
if( (pthread_mutex_unlock(&mutex_lecture)) != 0)
{
exitOnErrSyst("pthread_mutex_unlock","libération lecture file");
}
/* On signale qu'il y a quelque chose à lire dans cette case car la case a été lue */
if( (pthread_cond_signal(&cond_ecriture)) != 0)
{
fprintf(stdout,"Erreur Variable conditionnelle ecriture");
exit(1);
}
}
}
/***************************************************************************************************************************/
/* Thread Superviseur */
void* superviseur(void *arg)
{
int caract,retour_chariot;
int i,j;
while(1)
{
retour_chariot=getchar();
fprintf(terminal,"\n\t*******MENU SUPERVISEUR*******\n");
fprintf(terminal,"\n\t1 : Suspension Consommation\n");
fprintf(terminal,"\n\t2 : Reprise Consommation\n");
fprintf(terminal,"\n\t3 : Suspension Production\n");
fprintf(terminal,"\n\t4 : Reprise Production\n");
fprintf(terminal,"\n\t5 : Suspension Consommation et Production\n");
fprintf(terminal,"\n\t6 : Arret de l'application\n");
fprintf(terminal,"\n\t*******Tapez votre choix*******\n");
caract=getchar();
switch(caract)
{
case '1' : /*Suspension Consommation */
{
etatcons=0;
fprintf(terminal,"\n\t*******Consommation suspendue*******\n");
break;
}
case '2' : /*Reprise Consommation */
{
etatcons=1;
if( (pthread_cond_broadcast(&cond_lecture)) != 0)
{
fprintf(stdout,"Erreur reprise consommateurs");
}
fprintf(terminal,"\n\t*******Reprise Consommation*******\n");
break;
}
case '3' : /*Suspension Production */
{
etatprod=0;
fprintf(terminal,"\n\t*******Production suspendue*******\n");
break;
}
case '4' : /*Reprise Production */
{
etatprod=1;
if( (pthread_cond_broadcast(&cond_ecriture)) != 0)
{
fprintf(stdout,"Erreur reprise producteur");
}
fprintf(terminal,"\n\t*******Reprise production*******\n");
break;
}
case '5' : /*Suspension Consommation & Production */
{
etatprod=0;
etatcons=0;
fprintf(terminal,"\n\t*******Production & Consommation suspendues*******\n");
break;
}
case '6' : /*Arret de l'application */
{
/* premiere etape : envoi de reprise de tous les producteurs */
etatprod=1;
if( (pthread_cond_broadcast(&cond_ecriture)) != 0)
{
fprintf(stdout,"\n\nErreur reprise producteur");
}
/* envoi de reprise de tous les consommateurs */
etatcons=1;
if( (pthread_cond_broadcast(&cond_lecture)) != 0)
{
fprintf(stdout,"\n\nErreur reprise consommateurs");
}
/* envoi du signal de fin des consommateurs et producteurs */
arretprod=1;
arretcons=1;
fprintf(terminal,"\n\t*******Production & Consommation suspendues*******\n");
/* Attente terminaison producteurs avant de quitter la supervision */
for(i=0;i<nbprod;i++)
{
if( pthread_join(t_prod[i],NULL) != 0)
{
exitOnErrSyst("pthread_join","Attente terminaison thread producteurs");
}
fprintf(terminal,"\n\nSupervision : producteur %d termine\n",i+1);
}
/* Attente terminaison consommateur avant de quitter la supervision */
for(j=0;j<nbcons;j++)
{
if( pthread_join(t_conso[j],NULL) != 0)
{
exitOnErrSyst("pthread_join","Attente terminaison thread consommateurs");
}
fprintf(terminal,"\n\nSupervision : consommateur %d termine\n",j+1);
}
/* libération des threads qui attentent quelque chose a lire */
if((pthread_cond_broadcast(&cond_lecture)) != 0)
{
fprintf(stdout,"Erreur Attente lecture possible");
exit(1);
}
pthread_exit(NULL);
break;
}
default :
{
fprintf(terminal,"\n\t*******ERREUR DE SAISIE*******\n");
break;
}
}
}
}
/***************************************************************************************************************************/
/* Main */
int main(int argc, char**argv)
{
int fd,i,j,nb[2];
ctrlArg (argc,argv,2);
nbprod=atoi(argv[1]);
nbcons=atoi(argv[2]);
/* nb permet de savoir le nombre de consommateurs et de producteurs pour le thread de supervision */
nb[1]=nbprod;
nb[2]=nbcons;
if( (fd=(open("/dev/tty",O_WRONLY|O_APPEND))) == -1)
{
exitOnErrSyst("open","ouverture terminal");
}
if( (terminal=fdopen(fd,"ab+")) == NULL)
{
exitOnErrSyst("fdopen","ouverture du terminal en écriture");
}
fprintf(terminal,"\n\nVous avez opté pour %d producteurs et %d consommateurs",nb[1],nb[2]);
/* création des identifiants des threads */
t_conso = (pthread_t*)malloc(nbcons*sizeof(pthread_t));
t_prod = (pthread_t*)malloc(nbprod*sizeof(pthread_t));
/* Creation thread consommateur */
for(i=0;i<nbcons;i++)
{
if( pthread_create(&t_conso[i],NULL,consommateur,(void*)i+1) != 0)
{
exitOnErrSyst("pthread_create","thread consommateur");
}
}
/* Creation thread producteur */
for(j=0;j<nbprod;j++)
{
if( pthread_create(&t_prod[j],NULL,producteur,(void*)j+1) != 0)
{
exitOnErrSyst("pthread_create","thread producteur");
}
}
/* Création thread supervision */
if( pthread_create(&t_supervision,NULL,superviseur,NULL) != 0)
{
exitOnErrSyst("pthread_create","thread supervision");
}
/* Terminaison thread supervision */
if( pthread_join(t_supervision,NULL) != 0)
{
exitOnErrSyst("pthread_join","Attente terminaison thread de supervision");
}
fprintf(terminal,"\n\t*******ARRET DE L'APPLICATION*******\n");
return 0;
}