begin process at 2012 02 12 06:13:08
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C

 > 

Système

 > 

Autre

 > 

[UNIX]1 producteur N consomateurs


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

[UNIX]1 producteur N consomateurs

jeudi 18 juin 2009 à 22:08:27 | [UNIX]1 producteur N consomateurs

epmi212

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;
}
dimanche 21 juin 2009 à 18:05:10 | Re : [UNIX]1 producteur N consomateurs

SebLinck

Réponse acceptée !
Salut, Et quel est le problème ?

Cordialement,
Sébastien.
dimanche 21 juin 2009 à 18:13:49 | Re : [UNIX]1 producteur N consomateurs

epmi212

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
dimanche 21 juin 2009 à 18:44:49 | Re : [UNIX]1 producteur N consomateurs

SebLinck

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.


Cette discussion est classée dans : terminal, pthread, mutex, fprintf, if


Répondre à ce message

Sujets en rapport avec ce message

Ecrire dans un fichier [ par pitidragon ] Bonjour !Je viens vous demandez de l'aide pour un programme en C. J'ai réalisé un démineur, jouable sur console, et je dois rajouter une fonction mais Probleme threads [ par turnerom ] Bonjour, je n'arrive pas à compiler ce petit programme servant a illustrer mon problème :#include #include using namespace std;static pthread_mutex_t Problème utilisation pthread avec option static [ par ajollive ] Bonjour, j'ai un code qui gère un système multithreadé avec des mutex. J'ai une interface HTTP qui me permet d'ajouter ou de killer des threads. La p aidez moi svp [ par romain4700 ] salut tou le monde romain 19ans debutans c++ avec devc++ et microsoft visual c++ jai un problem je ne sais pas comment fair pour inseret un image dan Petite question sur if( x || y || z) [ par G0ss3Yn ] Bonjour, J'ai lu je ne sais plus où (ou en tout cas j'ai ça en tête) que le test [code=cpp]if( x || y || z) paf( ) ;[/code] est en fait la même chos Hook souris et Windows 7 64 bits [ par thenaoh ] Bonjour, Je cherche désespérément à faire fonctionner un hook souris basique réalisé en C++. Le hook doit fonctionner sous Windows 7 64 bits, où on p Traduction C [ par etudtelec ] Salut tous le monde, Je ne développe pas avec le langage C, je fais comme étude Réseaux Mais je viens devant une situation de réseaux et veux comprend Ouvrir un second terminal [ par lospepes ] Bonjour, J'espère que mon post sera au bon endroit sur le forum. Je cherche à ouvrir un seconde terminal avec mon applications en C pour y faire d'a probleme readfile sur port serie en overlapped [ par looloo78 ] Bonjour, je me permets de poster ce post concernant un programme pour lire sur le port COM1 ou 2. mais ca ne fonctionne pas, il se met automatiquemen


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,655 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales