Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/11/2008, à 16:50

babylone78

probleme de compilation gcc -l posix

Bonjour,

J'essaye de compiler un programme en C avec GCC et j'ai qq soucis.

Sur la station UNIX à l'ecole j'arrive trés bien à compiler mon programme en faisant
gcc -lpthread -lposix4 -o proj proj.c et le programme fonctionne correctement.

mais sous ubuntu il me dit ne pas connaitre la librairie posix4 et me fait une erreur de compilation à l'edition des liens.

si j'enleve cette bibliotheque en compilant avec gcc -pthread -o proj proj.c, le programme compile mais ne marche pas...

qqun aurait une explication et comment faire pour installer cette lib ?

Merci d'avance cool

Hors ligne

#2 Le 01/11/2008, à 19:42

nicolas.sitbon

Re : probleme de compilation gcc -l posix

Que fait cette bibliothèque? quand tu dis que le programme ne marche pas, peux tu détailler? peut on voir le code?

Hors ligne

#3 Le 02/11/2008, à 01:30

babylone78

Re : probleme de compilation gcc -l posix

hello,

je ne sais pas ce que fais cette bibliotheque, les threads de la lib pthread etant normalement dejà des threads POSIX,.... pour le programme , c'est juste un exo de producteurs consommateurs qui ecrivent et lisent dans une file. Il y a aussi un thread de supervision qui peut arreter ou demarrer les producteur ou les consommateurs.
quand je compile avec l'option -lposix4 ca donne :

/usr/bin/ld: cannot find -lposix4
collect2: ld a retourné 1 code d'état d'exécution

et sinon sans ca donne l'erreur :

*** glibc detected *** ./pro: free(): invalid pointer: 0xb7ec8780 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7de7a85]
/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7deb4f0]
./pro[0x8048f77]
/lib/tls/i686/cmov/libpthread.so.0[0xb7ed04fb]
/lib/tls/i686/cmov/libc.so.6(clone+0x5e)[0xb7e52e5e]
======= Memory map: ========

voici le code :

/*****************************************************/
/* programmation systeme                             */
/* version 2 : files d'attentes et thread d'affichage*/
/*****************************************************/
/* gcc -lpthread -lposix4 -o pro projet.c            */
/*****************************************************/

#define _REENTRANT
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>
#include <time.h>
/*********/
/* MACRO */
/*********/
 
#define TAILLE_FIFO 50

/************************/
/* variables globales   */
/************************/ 
/** synchronisation    **/
/************************/
pthread_cond_t _vMsgDispo = PTHREAD_COND_INITIALIZER;
pthread_cond_t _vPlaceDispo= PTHREAD_COND_INITIALIZER;
pthread_mutex_t _m_fifo =PTHREAD_MUTEX_INITIALIZER;

/************************/
/** gestion de la file **/
/************************/

char *_fifo[TAILLE_FIFO];
int _indiceLecture = 0;
int _indiceEcriture= 0;
int _msgEnFile     = 0;
int _ProdSuspendu  = 0;
int _ConsoSuspendu = 0;
int _arret =0 ;


/********************************************************/
/* fonction de controle du nombre et                    */
/* du type des arguments passés à la fonction main       */
/* affiche l'erreur sur la sortie d'erreur standard (2) */
/********************************************************/

void ctrlArg(int argc, char **argv, int nbArg, char **listeParam)
{ int i;
 if(argc!=(nbArg+1))
    {
      fprintf(stderr,"Nombre d'arguments incorrect\nUsage : %s [",argv[0]);
      for(i=0;i<nbArg;i++)
	{
	  fprintf(stderr," %s ",listeParam[i]);
	}
      fprintf(stderr,"]\n");
      exit(1);
    }  
}
/********************************************************/
/* fonction de renvoie d'un message d'erreur utilisateur */
/* suite a une erreur systeme */
/********************************************************/

void exitOnErrSyst(char *nomFonction, char *texte)
{
  char msg[512] ;
  sprintf(msg,"ERREUR fonction %s - %s :\n",nomFonction, texte);
  perror(msg);
  exit(1);
}

/*************************************/


void afficherMenu(FILE *fp)
{
  fprintf(fp,"-------------------------------------\n");
  fprintf(fp,"--      menu de supervision        --\n");
  fprintf(fp,"1 : suspension de consommation     --\n");
  fprintf(fp,"2 : reprise de la consonmmation    --\n");
  fprintf(fp,"3 : suspension de la production    --\n");
  fprintf(fp,"4 : reprise de la production       --\n");
  fprintf(fp,"5 : suspension de la prod et conso --\n");
  fprintf(fp,"6 : arret de l'application         --\n");
  fprintf(fp,"-------------------------------------\n");
}

/***********************/
/* gestion superviseur */
/***********************/

void *threadSuperviseur(void *arg)
{ 
  int c,commande_ok;
  int commande ;
  //int fd;
  FILE *fp;
  /* ouverture du terminal */
  arg=arg; /* evite le warning compilation */
  /* le superviseur ecrit sur le terminal courant */
  /* les affichages consommateurs et producteurs seront*/
  /* sur la sortie standart */
 
  if ((fp=fopen("/dev/tty","a+"))==NULL)
    {
      exitOnErrSyst("threadSuperviseur","erreur d'ouverture du terminal");
    }
  
    /*gestion superviseur*/
  
  while(1) /* boucle inf */
    {
      while((c=getchar())!='\n') {/* do nothing*/;}
      afficherMenu(fp);     
      commande_ok=0;
      while (!commande_ok)
	{ commande_ok=1;
	  /*scanf("%d\n",&commande);*/
	  commande = getchar(); 
	  /*fprintf(fp,"COMMANDE choisie : --%c-- \n",commande);*/
	  switch (commande)
	    {
	    case '1': case '2': 
	      {  
		pthread_mutex_lock(&_m_fifo);
		if (commande=='1') 
		  {_ConsoSuspendu =1;}
		else 
		  {_ConsoSuspendu = 0;}
		
		pthread_cond_broadcast(&_vMsgDispo);
		pthread_mutex_unlock(&_m_fifo);
		break;
	      }
	     
	    case '3':case '4':
	    {
	      pthread_mutex_lock(&_m_fifo);
	      if (commande=='3') 
		{_ProdSuspendu = 1;}
	      else
		{_ProdSuspendu = 0;}
	      
	      pthread_cond_broadcast(&_vPlaceDispo);
	      pthread_mutex_unlock(&_m_fifo);
	      break;
	    }
	    case '5':
	      {
		pthread_mutex_lock(&_m_fifo);
		_ProdSuspendu = 1; _ConsoSuspendu = 1;
		pthread_cond_broadcast(&_vPlaceDispo);
		pthread_cond_broadcast(&_vMsgDispo);
		pthread_mutex_unlock(&_m_fifo);
		break;
	      }
	    case '6':
	      {
		pthread_mutex_lock(&_m_fifo);
		_arret=1;
		pthread_cond_broadcast(&_vPlaceDispo);
		pthread_cond_broadcast(&_vMsgDispo);
		pthread_mutex_unlock(&_m_fifo);
		pthread_exit(arg);
	      break;
	      }; 
	    default: {commande_ok=0;fprintf(fp,"commande incorrecte (1--6), recommencez...\n");break;}
	    }
	}
    }
  fclose(fp);
}
/* ************** ***************/
/* renvoie la date courante sous*/
/* forme de chaine de caracteres*/
/********************************/
char *getHorodatage()
{
  time_t t;
  char *date;
  t = time(NULL);
  date = ctime(&t);
  return date;
}

/*****************************************/
/* fonction qui renvoie                  */
/* chaine quelconque de longueur definie */
/*****************************************/

char *getRandomChaine(int taille_chaine)
{ 
  int i;
  char *resu = (char *) malloc(sizeof(char) * taille_chaine);
  for(i=0;i<(taille_chaine-1);i++)
    {
      resu[i]='k';
    }
  resu[taille_chaine-1]='\0';
  return resu;
}

/********************************/
/* gestion des producteurs      */
/********************************/


void *threadProd(void *arg)
{ 
  char *date;
  int taille_chaine;
  unsigned int seed = 1547 ;
  int numProd = (int) (arg);
  char *chaine; 
  //fprintf(stdout,"Prod %d actif\n",numProd);
  while(1)
    {
      sleep(2);/* attente forcée entre deux productions */
       pthread_mutex_lock(&_m_fifo);	
       while(((_msgEnFile==TAILLE_FIFO) || (_ProdSuspendu==1)) && (_arret==0))
	 { /* suspension du thread */
	   if (_ProdSuspendu==1) 
	     {
	       fprintf(stdout,"Producteur numéro %d : Producteur en sommeil\n",numProd);
	     }
	   pthread_cond_wait(&_vPlaceDispo,&_m_fifo);
	 }
       /* arret du thread */
       if (_arret==1)
	 { 
	   pthread_mutex_unlock(&_m_fifo);
	   // fprintf(stdout,"Producteur numéro %d :Termine\n",numProd);
	   pthread_exit(arg);
	 }
       /* ecriture dans la fifo */
          /* creation du message */
       date = getHorodatage();
       taille_chaine =  (int)(rand_r(&seed)%10);
       chaine = getRandomChaine(taille_chaine);
       _fifo[_indiceEcriture]= (char *) malloc(sizeof(char)*taille_chaine);
       sprintf(_fifo[_indiceEcriture],"%s",chaine);
       fprintf(stdout,"%s : Prod n°%d : Ecriture case %d : chaine=\"%s\"\n",date,numProd,_indiceEcriture,chaine);
       free(date);
         /* maj des parametres de la fifo */
       _msgEnFile++;
       _indiceEcriture = (_indiceEcriture+1)%TAILLE_FIFO; 
       
       pthread_cond_signal(&_vMsgDispo);
       pthread_mutex_unlock(&_m_fifo);
    }
    
}

/*****************************/
/* gestion des consommateurs */
/*****************************/

void *threadConso(void *arg)
{ char *date;
  int numConso = (int) arg;
  //fprintf(stdout,"Conso %d actif\n",numConso);
  while(1)
    {
      sleep(1);
       pthread_mutex_lock(&_m_fifo);	
       while(((_msgEnFile==0) || (_ConsoSuspendu==1)) && (_arret==0))
	 { /* suspension du thread */
	   if (_ConsoSuspendu==1) 
	     {
	       fprintf(stdout,"Consommateur numéro %d : Consommateur en sommeil\n",numConso);
	     }
	  
	   pthread_cond_wait(&_vMsgDispo,&_m_fifo);
	 }

       /* arret du thread */
       if (_arret==1)
       { 
	 pthread_mutex_unlock(&_m_fifo);
	 //fprintf(stdout,"Consommateur numéro %d :Termine\n",numConso);
	 pthread_exit(arg);
       }
       
       /* lecture dans la fifo */
       date = getHorodatage();
       fprintf(stdout,"%s : Conso n°%d : lecture case %d : chaine=\"%s\"\n",date,numConso,_indiceLecture,_fifo[_indiceLecture]);
       free(date);
       free(_fifo[_indiceLecture]);

         /* maj des parametres de la fifo */
       _msgEnFile--;
       _indiceLecture = (_indiceLecture+1)%TAILLE_FIFO; 
       
       pthread_cond_signal(&_vPlaceDispo);
       pthread_mutex_unlock(&_m_fifo);
    }
}

/*********************************************/
/*                                           */
/*********************************************/
int main(int argc, char ** argv)
{
  pthread_t *idThreadConso; 
  pthread_t *idThreadProd;
  pthread_t idThreadSuperviseur;
   
  int nbrProd,nbrConso;
  int i;
  /* verification des parametres */
  char *param[3]={"nombre de consommateurs","nombre de producteurs",NULL};
  ctrlArg(argc,argv,2,param);
  sscanf(argv[1],"%d",&nbrProd);//printf("nbrprod : %d\n",nbrProd);
  sscanf(argv[2],"%d",&nbrConso);//printf("nbrconso : %d\n",nbrConso);
   
  /* creation des threads */
  /* allocation dynamique */
  idThreadConso =(pthread_t *) malloc(nbrConso*sizeof(pthread_t)); 
  idThreadProd  =(pthread_t *) malloc(nbrProd *sizeof(pthread_t)); 
  
  /*creation proprement dite */
  
  /* creation des threads de prod */
  for(i = 0; i < nbrProd; i++)
    { 
      if(pthread_create(&(idThreadProd[i]),NULL,threadProd,(void *) i)!=0)
	{
	  fprintf(stderr,"erreur creation du threadProd %d \n",i);
	  exit(1);
	}
     
    }
  /* creation des threads de conso */
  for(i = 0; i < nbrConso; i++)
    { 
      if(pthread_create(&(idThreadConso[i]),NULL,threadConso,(void *)i)!=0)
	{
	  fprintf(stderr,"erreur creation du threadConso %d \n",i);
	  exit(1);
	} 
     
  }
  /* creation thread superviseur */
  if(pthread_create(&idThreadSuperviseur,NULL,threadSuperviseur,NULL)!=0)
    {    
      fprintf(stderr,"erreur creation du thread Superviseur\n");
      exit(1);
    }
  /* attente de la terminaison des threads */
  for(i = 0; i < nbrProd; i++)   
    {
      pthread_join(idThreadProd[i],NULL); 
      /*manque affichage arret du prod  */
    }
  for(i = 0; i < nbrConso; i++)  
    {
      pthread_join(idThreadConso[i],NULL);
      /* manque affichage arret du conso */
    }
     
  pthread_join(idThreadSuperviseur,NULL);/* affichage arret du superviseur */
  /* liberation des donnees allouees */
  free(idThreadConso);
  free(idThreadProd);
  return 0;
}

voilà, tout ca n'est pas tres clair pour moi,

merci bien ! smile

Hors ligne

#4 Le 03/11/2008, à 10:34

morphoneo69

Re : probleme de compilation gcc -l posix

Le free n'a pas l'air de fonctionner. Peut-être faut-il plutot terminer les threads avec thread_exit : https://computing.llnl.gov/tutorials/pthreads/#CreatingThreads
Et sinon utilise gdb pour fixer le problème.

Hors ligne

#5 Le 15/11/2008, à 16:23

babylone78

Re : probleme de compilation gcc -l posix

Merci, je sais pas pourquoi ca ne marche pas sous Ubuntu mais ca marche tres bien sur Solaris.

Pour la compilation, apriori il n'y a effectivement pas besoin de la librairie posix4, elle est implicite sous ubuntu.

Merci pour votre aide !!!

Hors ligne

#6 Le 15/11/2008, à 17:30

nicolas.sitbon

Re : probleme de compilation gcc -l posix

babylone78 a écrit :

Merci, je sais pas pourquoi ca ne marche pas sous Ubuntu mais ca marche tres bien sur Solaris.

Pour la compilation, apriori il n'y a effectivement pas besoin de la librairie posix4, elle est implicite sous ubuntu.

Merci pour votre aide !!!

J'ai commencé à corriger, mais au vu du nombre de comportements indéterminés qu'il y a dans ton code, je préfère arrêter. Ubuntu n'y est pour rien. Le problème se situe plus entre la chaise et le clavier.
Quelques pistes comme ça :
-vérifie le retour et les paramètres de tes fonctions
-utilise des fonctions thread safe
-apprends à utiliser const

Cordialement.

Hors ligne

#7 Le 27/11/2008, à 14:59

inconnu

Re : probleme de compilation gcc -l posix

Salut babylone
tu serais pas en 07S par hasard....