PROLOG |NAME |SYNOPSIS |DESCRIPTION |RETURN VALUE |ERRORS |EXAMPLES |APPLICATION USAGE |RATIONALE |FUTURE DIRECTIONS |SEE ALSO |COPYRIGHT | |
SEMOP(3P) POSIX Programmer's ManualSEMOP(3P)This manual page is part of the POSIX Programmer's Manual. The Linux implementation of this interface may differ (consult the corresponding Linux manual page for details of Linux behavior), or the interface may not be implemented on Linux.
semop — XSI semaphore operations
#include <sys/sem.h> int semop(intsemid, struct sembuf *sops, size_tnsops);
Thesemop() function operates on XSI semaphores (see the Base Definitions volume of POSIX.1‐2017,Section 4.17,Semaphore). It is unspecified whether this function interoperates with the realtime interprocess communication facilities defined inSection2.8,Realtime. Thesemop() function shall perform atomically a user-defined array of semaphore operations in array order on the set of semaphores associated with the semaphore identifier specified by the argumentsemid. The argumentsops is a pointer to a user-defined array of semaphore operation structures. The implementation shall not modify elements of this array unless the application uses implementation-defined extensions. The argumentnsops is the number of such structures in the array. Each structure,sembuf, includes the following members: ┌────────────────┬───────────────┬──────────────────────────┐ │Member Type│Member Name│Description│ ├────────────────┼───────────────┼──────────────────────────┤ │unsigned short│sem_num │Semaphore number. │ │short│sem_op │Semaphore operation. │ │short│sem_flg │Operation flags. │ └────────────────┴───────────────┴──────────────────────────┘ Each semaphore operation specified bysem_op is performed on the corresponding semaphore specified bysemid andsem_num. The variablesem_op specifies one of three semaphore operations: 1. Ifsem_op is a negative integer and the calling process has alter permission, one of the following shall occur: * Ifsemval(see<sys/sem.h>) is greater than or equal to the absolute value ofsem_op, the absolute value ofsem_op is subtracted fromsemval. Also, if (sem_flg &SEM_UNDO) is non-zero, the absolute value ofsem_op shall be added to thesemadj value of the calling process for the specified semaphore. * Ifsemval is less than the absolute value ofsem_op and (sem_flg &IPC_NOWAIT) is non-zero,semop() shall return immediately. * Ifsemval is less than the absolute value ofsem_op and (sem_flg &IPC_NOWAIT) is 0,semop() shall increment thesemncnt associated with the specified semaphore and suspend execution of the calling thread until one of the following conditions occurs: -- The value ofsemval becomes greater than or equal to the absolute value ofsem_op. When this occurs, the value ofsemncnt associated with the specified semaphore shall be decremented, the absolute value ofsem_op shall be subtracted fromsemval and, if (sem_flg &SEM_UNDO) is non-zero, the absolute value ofsem_op shall be added to thesemadj value of the calling process for the specified semaphore. -- Thesemid for which the calling thread is awaiting action is removed from the system. When this occurs,errno shall be set to[EIDRM]and -1 shall be returned. -- The calling thread receives a signal that is to be caught. When this occurs, the value ofsemncnt associated with the specified semaphore shall be decremented, and the calling thread shall resume execution in the manner prescribed insigaction(3p). 2. Ifsem_op is a positive integer and the calling process has alter permission, the value ofsem_op shall be added tosemval and, if (sem_flg &SEM_UNDO) is non-zero, the value ofsem_op shall be subtracted from thesemadj value of the calling process for the specified semaphore. 3. Ifsem_op is 0 and the calling process has read permission, one of the following shall occur: * Ifsemval is 0,semop() shall return immediately. * Ifsemval is non-zero and (sem_flg &IPC_NOWAIT) is non- zero,semop() shall return immediately. * Ifsemval is non-zero and (sem_flg &IPC_NOWAIT) is 0,semop() shall increment thesemzcnt associated with the specified semaphore and suspend execution of the calling thread until one of the following occurs: -- The value ofsemval becomes 0, at which time the value ofsemzcnt associated with the specified semaphore shall be decremented. -- Thesemid for which the calling thread is awaiting action is removed from the system. When this occurs,errno shall be set to[EIDRM]and -1 shall be returned. -- The calling thread receives a signal that is to be caught. When this occurs, the value ofsemzcnt associated with the specified semaphore shall be decremented, and the calling thread shall resume execution in the manner prescribed insigaction(3p). Upon successful completion, the value ofsempid for each semaphore specified in the array pointed to bysops shall be set to the process ID of the calling process. Also, thesem_otime timestamp shall be set to the current time, as described inSection 2.7.1,IPC General Description.
Upon successful completion,semop() shall return 0; otherwise, it shall return -1 and seterrno to indicate the error.
Thesemop() function shall fail if:E2BIGThe value ofnsops is greater than the system-imposed maximum.EACCESOperation permission is denied to the calling process; seeSection 2.7,XSI Interprocess Communication.EAGAINThe operation would result in suspension of the calling process but (sem_flg &IPC_NOWAIT) is non-zero.EFBIGThe value ofsem_num is greater than or equal to the number of semaphores in the set associated withsemid.EIDRMThe semaphore identifiersemid is removed from the system.EINTRThesemop() function was interrupted by a signal.EINVALThe value ofsemid is not a valid semaphore identifier, or the number of individual semaphores for which the calling process requests a SEM_UNDO would exceed the system-imposed limit.ENOSPCThe limit on the number of individual processes requesting a SEM_UNDO would be exceeded.ERANGEAn operation would cause asemval to overflow the system- imposed limit, or an operation would cause asemadj value to overflow the system-imposed limit.The following sections are informative.
Setting Values in Semaphores The following example sets the values of the two semaphores associated with thesemid identifier to the values contained in thesb array. #include <sys/sem.h> ... int semid; struct sembuf sb[2]; int nsops = 2; int result; /* Code to initialize semid. */ ... /* Adjust value of semaphore in the semaphore array semid. */ sb[0].sem_num = 0; sb[0].sem_op = -1; sb[0].sem_flg = SEM_UNDO | IPC_NOWAIT; sb[1].sem_num = 1; sb[1].sem_op = 1; sb[1].sem_flg = 0; result = semop(semid, sb, nsops);Creating a Semaphore Identifier The following example gets a unique semaphore key using theftok() function, then gets a semaphore ID associated with that key using thesemget() function (the first call also tests to make sure the semaphore exists). If the semaphore does not exist, the program creates it, as shown by the second call tosemget(). In creating the semaphore for the queuing process, the program attempts to create one semaphore with read/write permission for all. It also uses the IPC_EXCL flag, which forcessemget() to fail if the semaphore already exists. After creating the semaphore, the program uses calls tosemctl() andsemop() to initialize it to the values in thesbuf array. The number of processes that can execute concurrently without queuing is initially set to 2. The final call tosemget() creates a semaphore identifier that can be used later in the program. Processes that obtainsemid without creating it check thatsem_otime is non-zero, to ensure that the creating process has completed thesemop() initialization. The final call tosemop() acquires the semaphore and waits until it is free; the SEM_UNDO option releases the semaphore when the process exits, waiting until there are less than two processes running concurrently. #include <stdio.h> #include <sys/sem.h> #include <sys/stat.h> #include <errno.h> #include <stdlib.h> ... key_t semkey; int semid; struct sembuf sbuf; union semun { int val; struct semid_ds *buf; unsigned short *array; } arg; struct semid_ds ds; ... /* Get unique key for semaphore. */ if ((semkey = ftok("/tmp", 'a')) == (key_t) -1) { perror("IPC error: ftok"); exit(1); } /* Get semaphore ID associated with this key. */ if ((semid = semget(semkey, 0, 0)) == -1) { /* Semaphore does not exist - Create. */ if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1) { /* Initialize the semaphore. */ arg.val = 0; sbuf.sem_num = 0; sbuf.sem_op = 2; /* This is the number of runs without queuing. */ sbuf.sem_flg = 0; if (semctl(semid, 0, SETVAL, arg) == -1 || semop(semid, &sbuf, 1) == -1) { perror("IPC error: semop"); exit(1); } } else if (errno == EEXIST) { if ((semid = semget(semkey, 0, 0)) == -1) { perror("IPC error 1: semget"); exit(1); } goto check_init; } else { perror("IPC error 2: semget"); exit(1); } } else { /* Check that semid has completed initialization. */ /* An application can use a retry loop at this point rather than exiting. */ check_init: arg.buf = &ds; if (semctl(semid, 0, IPC_STAT, arg) < 0) { perror("IPC error 3: semctl"); exit(1); } if (ds.sem_otime == 0) { perror("IPC error 4: semctl"); exit(1); } } ... sbuf.sem_num = 0; sbuf.sem_op = -1; sbuf.sem_flg = SEM_UNDO; if (semop(semid, &sbuf, 1) == -1) { perror("IPC Error: semop"); exit(1); }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 inSection 2.7,XSI Interprocess Communication can be easily modified to use the alternative interfaces.
None.
None.
Section 2.7,XSI Interprocess Communication,Section 2.8,Realtime,exec(1p),exit(3p),fork(3p),semctl(3p),semget(3p),sem_close(3p),sem_destroy(3p),sem_getvalue(3p),sem_init(3p),sem_open(3p),sem_post(3p),sem_trywait(3p),sem_unlink(3p) The Base Definitions volume of POSIX.1‐2017,Section 4.17,Semaphore,sys_ipc.h(0p),sys_sem.h(0p),sys_types.h(0p)
Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1-2017, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 7, 2018 Edition, Copyright (C) 2018 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online athttp://www.opengroup.org/unix/online.html . Any typographical or formatting errors that appear in this page are most likely to have been introduced during the conversion of the source files to man page format. To report such errors, seehttps://www.kernel.org/doc/man-pages/reporting_bugs.html .IEEE/The Open Group 2017SEMOP(3P)Pages that refer to this page:sys_sem.h(0p), ipcs(1p), exec(3p), _Exit(3p), fork(3p), sem_close(3p), semctl(3p), sem_destroy(3p), semget(3p), sem_getvalue(3p), sem_open(3p), sem_post(3p), sem_timedwait(3p), sem_trywait(3p), sem_unlink(3p)
HTML rendering created 2025-09-06 byMichael Kerrisk, author ofThe Linux Programming Interface. For details of in-depthLinux/UNIX system programming training courses that I teach, lookhere. Hosting byjambit GmbH. | ![]() |