Undefined Reference issues using Semaphores

63,150

Solution 1

If you are on a linux system, you'll need to compile and link with the -pthread flag to link the pthreads library.

gcc -pthread Producers_Consumers.c

As Paul Griffiths has pointed out, you can also use -lrt, which is more portable, and links the POSIX Realtime Extensions library

gcc Producers_Consumers.c -lrt

Other notes specific to the code in the question:

  • int main(void) not void main()
  • typedef int semaphore is wrong, sem_t should be treated as an opaque type, you never use this typedef in your code anyway.
  • A problem I foresee is that your consumer code uses the semaphores before they are initialized in producer. You should initialize them in your main

Solution 2

Got same error in ubuntu qt. After adding

LIBS += -lpthread -lrt

to project.pro file all compiled fine.

Share:
63,150
TheFatness
Author by

TheFatness

Updated on May 18, 2021

Comments

  • TheFatness
    TheFatness almost 3 years

    I am playing around with using Semaphores, but I keep encountering Undefined Reference warnings, thus causing my code not to work. I pulled example code from a text, but was having issues with some of their syntax, so I went to POSIX's semaphore tutorial and changed things around to their syntax and as a result am now getting these reference errors.

    I may simply be overlooking something, but I cannot find it.

    Errors:

    Producers_Consumers.c:52: warning: return type of ‘main’ is not ‘int’
    /tmp/cceeOM6F.o: In function `producer':
    Producers_Consumers.c:(.text+0x1e): undefined reference to `sem_init'
    Producers_Consumers.c:(.text+0x3a): undefined reference to `sem_init'
    Producers_Consumers.c:(.text+0x46): undefined reference to `sem_wait'
    Producers_Consumers.c:(.text+0x52): undefined reference to `sem_wait'
    Producers_Consumers.c:(.text+0x5e): undefined reference to `sem_post'
    Producers_Consumers.c:(.text+0x6a): undefined reference to `sem_post'
    /tmp/cceeOM6F.o: In function `consumer':
    Producers_Consumers.c:(.text+0x7e): undefined reference to `sem_wait'
    Producers_Consumers.c:(.text+0x8a): undefined reference to `sem_wait'
    Producers_Consumers.c:(.text+0x96): undefined reference to `sem_post'
    Producers_Consumers.c:(.text+0xa2): undefined reference to `sem_post'
    collect2: ld returned 1 exit status
    

    What I have (It may look a bit ugly due to the way I commented things out from my old method) I also know my adding method won't work, but I'll get to that when I fix my syntax issues:

    #include <stdio.h>
    #include <semaphore.h>
    #include <string.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <errno.h>
    
    #define N 10     //Number of slots in buffer
    typedef int semaphore;  //Semaphores ae a special kind of int
    sem_t mutex; //Controls access to critical region 1
    sem_t empty;  //Counts empty buffer slots N
    sem_t  full;  //Counts full buffer slots 0
    int count = 0; //What we're putting in 
    //int buffer[N];
    
    void producer(void) {
        sem_init(&mutex, 0, 1);
        //sem_init(&empty, 0, N);
        sem_init(&full, 0, 0);
    
        while(1) { 
            sem_wait(&empty);
            sem_wait(&mutex);
            //printf("Empy: %d\n",empty);
            //printf("Mutex: %d\n",mutex);
            //printf("Both Downs Ran\n");
            //buffer = buffer + 1;
            sem_post(&mutex);
            sem_post(&full);
            //printf("Producer produced: %d\n",buffer);
        }
    }
    
    void consumer(void) {
        while(1) { 
            sem_wait(&full);
            sem_wait(&mutex);
            //item = buffer;
            sem_post(&mutex);
            sem_post(&empty);
            //printf("Consumer consumed: %d/n",item);
        }
    }
    
    void main() {
    
    }
    
  • Crowman
    Crowman almost 10 years
    You may need -lrt, and the libraries should go after the .c file.
  • TheFatness
    TheFatness almost 10 years
    Wow. Just wow. I knew I was overlooking something simple. This solved my original issue. Thanks! As for the main... I know, I was experimenting and forgot to change it back!
  • Ryan Haining
    Ryan Haining almost 10 years
    @PaulGriffiths thanks, updated. For reader's reference, -pthread isn't the same as the linked command -lpthread, and does a bit more, which is why it doesn't have to follow the c files
  • krb686
    krb686 almost 9 years
    I've tried -lrt, -lpthread, and -pthread because every source I read cites something different, and none of them work. The command is gcc -c ./src/server.c -lrt/pthread/lpthread
  • krb686
    krb686 almost 9 years
    @RyanHaining Sorry it got fixed. I wasn't following the gcc ordering of args and files