c-使用-lrt的Posix信号量编译错误



可能重复:
sem_open()错误:“对sem_open()的未定义引用”在linux上(Ubuntu 10.10)

posix信号量的编译有问题。我的目标是创建一个共享内存段,并通过信号量来保护它。共享内存运行良好,但信号量代码会给我带来编译错误,即使我包含了信号量.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 = '';
        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. %dn", (int)(err));

    }

} 

这是生成文件:

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)

我一直收到这个错误:

george@george-System-Product-Name:~/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

我认为你也应该链接到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 $@
.cpp.o:
        $(CC) $(CFLAGS) $< -o $@
clean:
    rm -rf *.o ${EXECUTABLE}

做完这件事后,你会感到小腿酸痛。

编译跟踪显示:

$ 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)

最新更新