Skip to content
Advertisement

Strange POSIX semaphore behavior (stuck on sem_wait on Linux)

I’m trying to solve a school problem envolving POSIX semaphores. I’ve run into an issue that I’ve narrowed down to this simplified code:

sem_t sem;

void parent() {
    printf("waiting...n");
    sem_wait(&sem);
    printf("done!n");
}

void child() {
    sem_post(&sem);
    printf("go!n");
    exit(0);
}

int main() {
    sem_init(&sem, 1, 0);

    if(!fork())
        child();

    parent();

    sem_destroy(&sem);

    exit(0);
}

When compiling (using gcc -Wall -pthread sems.c -o sems) and running this program in Linux, I get the following output (the program doesn’t finish execution):

waiting... 
go!

Because I call sem_post(&sem) in the child process, I would expect the parent process to move past the sem_wait(&sem) and the output to be:

waiting...
go!
done!

Even more bizarre, out of curiosity, I tried testing it on Windows using CLion (Cygwin compiler), and the program worked as intended. What am I missing here?

Advertisement

Answer

From the man page of sem_init():

If pshared is nonzero, then the semaphore is shared between processes, and should be located in a region of shared memory (see shm_open(3), mmap(2), and shmget(2)). (Since a child created by fork(2) inherits its parent’s memory mappings, it can also access the semaphore.)

Your sem variable is not allocated in shared memory; therefore it can not be shared between processes despite a non-zero pshared argument. Each process has its own unique instance of the semaphore.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement