home blog portfolio Ian Fisher

POSIX semaphores do not auto-release on exit

A Recurser mentioned to me that the jobserver used by GNU Make controls concurrency by having child processes read a byte from a named pipe to get an available job, and write it back when finished.

This mechanism has the defect that if a child crashes without writing back the byte, then one concurrency slot will be lost forever.

I wondered whether the problem could be avoided by using POSIX semaphores (sem_overview(7)) instead, on the assumption that the kernel would automatically release a child process's hold on a semaphore no matter how it exited.

In fact, POSIX semaphores do not auto-release on exit (at least on Linux), as this test program shows. The parent process creates a semaphore with initial value 4 and forks off a child which calls sem_wait twice then exits. When the parent reads the final value of the semaphore, it is 2, not 4. This remains true even if the child process calls sem_close.

See also