[UNIX]1 producteur N consomateurs

Résolu
epmi212 Messages postés 2 Date d'inscription mardi 29 janvier 2008 Statut Membre Dernière intervention 21 juin 2009 - 18 juin 2009 à 22:08
SebLinck Messages postés 212 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 23 juin 2011 - 21 juin 2009 à 18:44
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
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include
#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;
}

3 réponses

SebLinck Messages postés 212 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 23 juin 2011
21 juin 2009 à 18:05
Salut,

Et quel est le problème ?

Cordialement,
Sébastien.
3
epmi212 Messages postés 2 Date d'inscription mardi 29 janvier 2008 Statut Membre Dernière intervention 21 juin 2009
21 juin 2009 à 18:13
salut
merci de m'avoir répondu enfin s'intersser à ma question
oféte c que quand je complie j'ai un message d'erreur et je vois pas le probleme!
est ce que c'est possible que vous regarder et essayer de le compiler car moi je vois pas du tout le probleme
merci bien
bien à vous
0
SebLinck Messages postés 212 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 23 juin 2011
21 juin 2009 à 18:44
Salut,
Copier collé de ton code dans un fichier main.c,
ensuite "make main" dans une console, le programme compile sans probème, pas le moindre avertissement ...

Cordialement,
Sébastien.
0
Rejoignez-nous