2012-01-19 4 views
1

Possible Duplicate:
sem_open() error: “undefined reference to sem_open()” on linux (Ubuntu 10.10)ошибка компиляции Posix Семафор с помощью -lrt

Возникли проблемы с составлением Posix семафоры. Моя цель - создать сегмент разделяемой памяти и защитить его с помощью семафоров. разделяемая память работает нормально, но семафоры код дает мне ошибку компиляции, даже если я включил semaphore.h и добавил -lrt к флагам компиляции

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <semaphore.h> 
#include <time.h> 


int main (int argc, char** argv) { 
    FILE *configFile; 
    int i,j; 


    int CashDesksNo=0; 
    int maxCashDesksNo; 
    int n,m; 
    int TmaxServe; 
    int custPerc; //customer ratio policy 
    int maxCapacity; 


    char * nlptr=NULL; 
    char * pch=NULL; 
    char line[125]; 

    char termInput[30]; 
    char tmpString[40]; 

    int flg1,flg2; 
    int flag; 

    int execResult=0; 
    int fd; 
    int rc; 

    int randNum; 

    int status; 
    pid_t ch_pid; 

    int a,b,c; 
    int shmid=0; 
    int *shm_ptr; 
    int * err; 

    int retval; 
    sem_t *sp; 
    char semName[10]; 

    strcpy(semName,"mutex"); 
    //---------- Davasma kai elegxos in line parameters----------------- 
     // read inline params and config file  
           . 
           . 
           . 

    //------------ Print Configuration Data ---------------------------- 
    if(CashDesksNo>maxCashDesksNo || CashDesksNo<1) 
    { 
     printf("\n# of Cash Desks should be between 1 and %d",maxCashDesksNo); 
     printf("\nsupermarket will now exit...\n"); 
     exit(1); 
    } 

    printf("\n//-----------------------------------------------"); 
    printf("\nSupermarket initialization"); 
    printf("\n# of Cash Desks: %d",CashDesksNo); 
    printf("\n# of max products: %d",n); 
    printf("\nMax price: %d",m); 
    printf("\nMaximum serving time(secs): %d",TmaxServe); 
    printf("\n%% Customer/Cashier Percentage: %d/%d",custPerc,100-custPerc); 
    printf("\nMax Supermarket capacity: %d",maxCapacity); 
    printf("\n//-----------------------------------------------\n"); 

    printf("\nAbout to create customer and cashier processes"); 

// ----------- Shared Memory Attachment -------------------------------- 
shmid=shmget(IPC_PRIVATE,sizeof(int*),0666); 

if (shmid < 0) 
{ 
    perror("shmget"); 
    exit(1); 
} 

shm_ptr=(int*)shmat(shmid,(void *)0,0); 

if (shm_ptr == (int *)(-1)) 
{ 
    perror("shmat"); 
    exit(1); 
} 

a=0; //shm 
shm_ptr=(int*)a; 
printf("shmPtr:%d",(int)shm_ptr); 



// ----- create & initialize semaphore --------------------------------- 

    sp = sem_open(semName,O_CREAT,0644,1); 
    if(sp == SEM_FAILED) 
    { 
     perror("unable to create semaphore"); 
     exit(-1); 
    } 


    while(1) 
    { 
     printf("\nPress enter to start a new day at the supermarket(type exit to quit)\n"); 
     fgets(termInput,sizeof(termInput),stdin); 

     nlptr = strchr(termInput, '\n');// termatismos string 
     if (nlptr) *nlptr = '\0'; 

     if(strcmp(termInput,"exit")==0)//exit apo tin efarmogi 
     { 
      printf("\nExiting Supermarket..\n"); 
      exit(0); 
     } 

     i=0; 
     while(i<maxCapacity) 
     { 


      //-Fork new process for the simulation -------------------- 

      ch_pid = fork(); 

      if (ch_pid == -1) { 
      perror("\nFailed to fork initial spliter/merger process \n"); 
      exit(1); 
      } 


      if (ch_pid == 0) //this is the child process 
      { 
      srand (getpid());//pid based seed 

      // "itoa" - Metatropi ari8mou se string 
      sprintf(tmpString, "%d", shmid); 

      randNum=rand() % 100 + 1; 
      if(randNum<custPerc)// customer : cashier ratio 
      { 
       execResult=execl("customer","customer","0",tmpString,NULL); 
       //printf("\nCreated a customer,randNum %d",randNum); 
      }else 
      { 
       execResult=execl("cashier","cashier","0",tmpString,NULL); 
       //printf("\nCreated a cashier,randNum %d",randNum); 

      } 

       if(execResult==-1) 
       { 
        perror("Could not perform exec to create cashier/customer process"); 
       } 

      } 
     i++;   
     } 

     //Root process 
     //wait for childs to terminate 
       for (i = 0; i < maxCapacity; ++i) 
       { 
        waitpid(-1,&status,0); 
       } 
     printf("supermarket shared memory content: %d",(int)shm_ptr); 
     sem_close(sp); 
     sem_unlink(semName); 

     err = (int*)shmctl(shmid, IPC_RMID, 0); 
     if (err == -1) 
      perror ("Shared Memory Removal."); 
     else 
      printf("Shared Memory Removed. %d\n", (int)(err)); 


    } 



} 

это Makefile:

OBJS = supermarket.o cashier.o customer.o 
SOURCE = supermarket.c cashier.c customer.c 
HEADER = struct.h 
OUT  = supermarket cashier customer 
CC = gcc 
FLAGS = -lrt -g -c 
LIBS = -lm 
# -g option enables debugging mode 
# -c flag generates object code for separate files 
# -lm math library 

all: supermarket cashier customer 

supermarket: supermarket.c 
    $(CC) supermarket.c -o supermarket 

cashier: cashier.c 
    $(CC) cashier.c -o cashier 

customer: customer.c 
    $(CC) customer.c -o customer 


# clean house 
clean: 
    rm -f $(OBJS) $(OUT) 

# do a bit of accounting 
count: 
    wc $(SOURCE) $(HEADER) 

я получаю эту ошибку:

[email protected]:~/Desktop/prj3$ make 
gcc supermarket.c -o supermarket 
supermarket.c: In function ‘main’: 
supermarket.c:310:11: warning: comparison between pointer and integer [enabled by default] 
/tmp/ccYxA2Wi.o: In function `main': 
supermarket.c:(.text+0x75c): undefined reference to `sem_open' 
supermarket.c:(.text+0x9b0): undefined reference to `sem_close' 
supermarket.c:(.text+0x9bf): undefined reference to `sem_unlink' 
collect2: ld returned 1 exit status 
make: *** [supermarket] Error 1 

что я могу сделать? это проект для класса операционных систем, моя система Linux Ubuntu

+0

Возможно, функция семафора POSIX не включена в системе. Раньше это была необязательная часть POSIX (но теперь она находится в базовой функциональности). Какую версию Ubuntu вы используете? –

ответ

2

Я думаю, вы должны связать с PTHREAD, а также:

-lpthread 

Пример Makefile из старого проекта шахты (см комментарии):

CC=gcc 
CFLAGS=-c -Wall -O3 -g 
LDFLAGS=-pthread 
SOURCES=chatzor.c clientlist.c messagequeue.c 
OBJECTS=$(SOURCES:.cpp=.o) 
EXECUTABLE=chatzor_server 

all: $(SOURCES) $(EXECUTABLE) 

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected] 

.cpp.o: 
     $(CC) $(CFLAGS) $< -o [email protected] 

clean: 
    rm -rf *.o ${EXECUTABLE} 
+1

Нету, попытался это: ФЛАГИ = -lrt -g -c -lpthread и что: ФЛАГИ = -g -c -lpthread ничего не изменилось это проблема конфигурации системы? –

+1

Ну, вы не включаете флаги в свой файл makefile (см. Его вывод), сначала попытайтесь исправить это. –

+0

Thats it, thanks! :) просто использовал предыдущие проекты makefile и забыл об этом! –

0

У вас будут больные голени, как только вы закончите с этим.

Компиляция след говорит:

$ make 
gcc supermarket.c -o supermarket 
supermarket.c: In function ‘main’: 
... 

Ваш Makefile говорит:

supermarket: supermarket.c 
    $(CC) supermarket.c -o supermarket 

Он должен сказать (как минимум):

supermarket: supermarket.c 
    $(CC) supermarket.c -o supermarket $(LIBS) 

В самом деле, это, вероятно, следует говорить:

supermarket: supermarket.c 
    $(CC) $(CFLAGS) supermarket.c -o supermarket $(LDFLAGS) $(LIBS) 
Смежные вопросы