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.