DNOSKOV
DNOSKOV

Reputation: 21

Linker can't find semaphore functions

I'm trying to make a C programm, that will execute subprocesses, which will be interact using semaphore. Then I compile code, gcc throw referencing error - because it doesn't know about functions "sem_init", "sem_post" and "sem_wait", even though I include semaphore.h library.

Here's how it look:

Code:

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>

#define LETTER_COUNT 26
#define THREADS 2

char letter[LETTER_COUNT] = "aBCDefghiJklMNoPqrsTuvWxyZ";

pthread_t t[THREADS];
sem_t sem[THREADS];

void print_letter(void) {
    //print string
}

void* reorder(void* d) {
    (void)d;
    //do some work
    return NULL;
}

void* switch_case(void* d) {
    (void)d;
    //do some work
    return NULL;
}

int main(void) {
    int i;
    for(i = 0; i < THREADS; i++) {
        if(sem_init(&sem[i], 0, 0) == -1) {
            perror("sem_init");
            return -1;
        }
    }
    pthread_create(&t[0], NULL, reorder, NULL);
    pthread_create(&t[1], NULL, switch_case, NULL);
    while(1) {
        i = (i + 1) % (THREADS - 1);
        sem_post(&sem[i]);
        sem_wait(&sem[2]);
        print_letter();
        sleep(1);
    }
    return 0;
}

Error:

gcc -Wall task4.c -o task4.o
Undefined                       first referenced
 symbol                             in file
sem_init                            /var/tmp//cc0i56ka.o
sem_post                            /var/tmp//cc0i56ka.o
sem_wait                            /var/tmp//cc0i56ka.o
ld: fatal: symbol referencing errors. No output written to task4.o
collect2: ld returned 1 exit status

I'm trying to find some information about this problem, but I can't find any working solutions. Maybe I should use some compilation flag (like -lsocket)?

Upvotes: 2

Views: 3500

Answers (1)

dash-o
dash-o

Reputation: 14452

As per man sem_init (and friends)

gcc -Wall task4.c -o task4.o -lpthread

On some system, the 'librt' shared library is built against shared libpthread, and referencing -lrt will imply -lpthread. However the man page indicate the proper command to link is to use -pthread, see below. Note that -pthread will invoke MT semantics, as needed, usually -lpthread, but other libraries, flags or #defines. For example, on GCC/Mint19, it will define -D_REENTRANT.

From man sem_init

AME sem_init - initialize an unnamed semaphore

SYNOPSIS #include

   int sem_init(sem_t *sem, int pshared, unsigned int value);

   Link with -lpthread.

From man gcc

Options Controlling the Preprocessor

   -pthread
       Define additional macros required for using the POSIX threads library.  You should use this option consistently for both compilation
       and linking.  This option is supported on GNU/Linux targets, most other Unix derivatives, and also on x86 Cygwin and MinGW targets.

Options for Linking

  -pthread
       Link with the POSIX threads library.  This option is supported on GNU/Linux targets, most other Unix derivatives, and also on x86
       Cygwin and MinGW targets.  On some targets this option also sets flags for the preprocessor, so it should be used consistently for both
       compilation and linking.

Upvotes: 2

Related Questions