In order to use unnamed POSIX semaphores with multiple processes one has to create/obtain access to a portion of shared memory.
After that, one process has to initialize the semaphore by calling sem_init
with a reference to the shared memory as first parameter.
However, this is only allowed to be done once!
POSIX says:
Attempting to initialize an already initialized semaphore results in undefined behavior.
The problem is that there is no way to test if the semaphore already exists and is initialized, and to initialize it if not, in an atomic way.
One might be tempted to simply add a boolean flag to the shared memory that indicates if the semaphore was already initialized but that obviously produces a race condition - something one definitely does not want when working with semaphores :)
XSI (aka System V) semaphores require some rather convoluted way to initialize properly without races but it can be made safe (cf. the implementation in APUE for example). Also, named POSIX semaphores do not show this problem either since sem_open
accepts the O_EXCL
flag and can initialize the value of the semaphore as well.
So, how is one supposed to share unnamed POSIX semaphores between processes safely without relying on other ways to synchronize or forking the other processes only after initializing the semaphore? What do I miss?