What are the differences between the functions included in <semaphore.h>
and <sys/sem.h>
?
Does exist a situation where is better to use a header or the other?
<sys/sem.h>
provides the interface for XSI (originally Unix System V) semaphores. These are not part of the base POSIX standard (they're in the XSI option which is largely for traditional Unix compatibility) and while they are not considered obsolescent/deprecated yet, many programmers consider them deprecated, and POSIX advises:
APPLICATION USAGE
The POSIX Realtime Extension defines alternative interfaces for interprocess communication. Application developers who need to use IPC should design their applications so that modules using the IPC routines described in XSI Interprocess Communication can be easily modified to use the alternative interfaces.
The advantages and disadvantages of XSI semaphores is that they are, and must be due to the way their interface works, kernel-space objects. The main benefit this gives you is the ability to set them up so that the kernel can back-out operations if the process exits or is killed unexpectedly. The main cost is that every operation is a round-trip to kernel-space, i.e. they're very slow. The interfaces for using them are also very obtuse and hard to learn, and they're necessarily a process-shared resource, meaning you have to deal with a shared namespace and resource cleanup issues.
<semaphore.h>
defines POSIX semaphores, which are designed in such a way that they can be implemented entirely in userspace, except in the contended case where the process will call into the kernel to go to sleep. Their performance should be near-optimal (i.e. almost impossible to beat rolling your own) but they're not quite as featureful as XSI semaphores. POSIX semaphores also offer you the choice of whether you want a process-local semaphore (for use in a multi-threaded environment, or even, in some conditions, a signal handler in a single-threaded program) or a process-shared one, and in the latter case, you also have the choice whether to let the system handle allocating it in a shared namespace by name, or to obtain shared memory yourself and initialize it in shared memory.