#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
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 !
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
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....