sem_open()

Updated: April 19, 2023

Create or access a named semaphore

Synopsis:

#include <semaphore.h>
#include <fcntl.h>

sem_t * sem_open( const char * sem_name,
                  int oflags,
                  ... );

Arguments:

sem_name
The name of the semaphore that you want to create or access, or SEM_ANON (implies O_ANON, which also implies O_CREAT).
When you create an anonymous named semaphore (see below), this argument is ignored.
oflags
Flags that affect how the function creates a new semaphore. This argument is a combination of:
  • O_ANON
  • O_CREAT
  • O_EXCL
Note: Don't set oflags to O_RDONLY, O_RDWR, or O_WRONLY. According to POSIX, a semaphore's behavior is undefined with these flags. The QNX Neutrino libraries silently ignore these options, but they may reduce your code's portability.

For more information, see below.

If you set O_CREAT in oflags, you must also pass the following arguments:

mode_t mode
The semaphore's mode (just like file modes). For portability, you should set the read, write, and execute bits to the same value. An easy way of doing this is to use the constants from <sys/stat.h>:
  • S_IRWXG for group access.
  • S_IRWXO for other's access.
  • S_IRWXU for your own access.

For more information, see the entry for struct stat.

When you create an anonymous named semaphore, you must provide this argument, but it is ignored.
unsigned int value
The initial value of the semaphore. A positive value indicates the number of semaphore wait operations (e.g., sem_wait()) that will succeed without blocking, and a value of zero indicates that the next semaphore wait operation will block the calling thread. This value must not exceed SEM_VALUE_MAX.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The sem_open() function creates or accesses a named semaphore. Semaphores persist as long as the system is up.

The sem_open() function returns a semaphore descriptor that you can use with sem_wait(), sem_trywait(), and sem_post(). You can use it until you call sem_close(). You can unlink the semaphore by calling sem_unlink(); when all processes have unlinked the semaphore, it's destroyed.

Named semaphores are always created under /dev/sem:

In either case, slash characters other than the leading slash character aren't interpreted, and the specified name, including these slash characters, is used to identify the semaphore. In other words, additional slashes don't create a directory structure under /dev/sem.

For example, if your current directory is /tmp:

name Pathname space entry
/my_sem /dev/sem/my_sem
my_sem /dev/sem/tmp/my_sem

The oflags argument is used only for semaphore creation. When creating a new semaphore, you can set oflags to O_CREAT, (O_CREAT|O_EXCL), or O_ANON:

O_ANON
Implies O_CREAT. When you're creating a new named semaphore, make it an anonymous named semaphore.

Anonymous named semaphores don't have a path like other named semaphores (i.e., named semaphores with names), but they do have some advantages over unnamed semaphores. Specifically:

  • A named semaphore (including an anonymous named semaphore) can be posted by a sigevent (e.g., returned from an ISR or delivered by a server).
  • An anonymous named semaphore can be shared between a parent and a child process across a fork() without requiring a shared mapping

With anonymous named semaphores, the sem_name and mode arguments are ignored.

O_CREAT
Create a new named semaphore. If you set this bit, you must provide the mode and value arguments to sem_open().
O_EXCL
When you're creating a new named semaphore, O_EXCL causes sem_open() to fail if a semaphore with sem_name already exists. Without O_EXCL, sem_open() attaches to an existing semaphore or creates a new one if sem_name doesn't exist.
CAUTION:
Don't mix named semaphore operations (sem_open() and sem_close()) with unnamed semaphore operations (sem_init() and sem_destroy()) on the same semaphore.

The QNX implementation of named semaphores

Note that the QNX implementation of semaphores differs from the POSIX standard, which requires that “if a process makes multiple successful calls to sem_open() with the same value for name, the same semaphore address shall be returned for each such successful call ...”.

With the QNX implementation of named semaphores, if a process makes multiple successful calls to sem_open() with the same value for the name (sem_name) all calls to the function will return sem_t objects that reference the same underlying object. This behavior is as specified in the POSIX standard.

However, the QNX implementation of named semaphores differs from the behavior specified in the POSIX standard as follows: the semaphore addresses returned for each such successful call to sem_open() will be unique (i.e, call 1 will return address A, while call 2 will return address B, etc.). This behavior means that, for every semaphore, when you are done with the semaphore you must match the call you made to sem_open() with a call to sem_close().

Returns:

A pointer to the created or accessed semaphore, or SEM_FAILED for failure (errno is set).

Errors:

EACCES
Either the named semaphore exists and you don't have permission to access it, or you're trying to create a new semaphore and you don't have permission.
EEXIST
You specified O_CREAT and O_EXCL in oflags, but the semaphore already exists.
EINTR
The call was interrupted by a signal.
EINVAL
The sem_name argument is invalid or, when you're creating a semaphore, value is greater than SEM_VALUE_MAX.
ELOOP
Too many levels of symbolic links or prefixes.
EMFILE
The process is using too many files or semaphores.
ENFILE
The system ran out of resources and couldn't open the semaphore.
ENOENT
The semaphore identified by the sem_name argument doesn't exist and you didn't specify O_CREAT in oflags.
ENOMEM
There isn't enough memory to create the new named semaphore.

Classification:

POSIX 1003.1

Safety:  
Cancellation point No
Interrupt handler No
Signal handler No
Thread Yes