1SEMOP(3P)                  POSIX Programmer's Manual                 SEMOP(3P)
2
3
4

PROLOG

6       This  manual  page is part of the POSIX Programmer's Manual.  The Linux
7       implementation of this interface may differ (consult the  corresponding
8       Linux  manual page for details of Linux behavior), or the interface may
9       not be implemented on Linux.
10
11

NAME

13       semop — XSI semaphore operations
14

SYNOPSIS

16       #include <sys/sem.h>
17
18       int semop(int semid, struct sembuf *sops, size_t nsops);
19

DESCRIPTION

21       The semop() function operates on XSI semaphores (see the  Base  Defini‐
22       tions volume of POSIX.1‐2008, Section 4.16, Semaphore).  It is unspeci‐
23       fied whether this function interoperates with the realtime interprocess
24       communication facilities defined in Section 2.8, Realtime.
25
26       The  semop()  function shall perform atomically a user-defined array of
27       semaphore operations in array order on the set of semaphores associated
28       with the semaphore identifier specified by the argument semid.
29
30       The  argument  sops  is  a pointer to a user-defined array of semaphore
31       operation structures. The implementation shall not modify  elements  of
32       this  array  unless  the application uses implementation-defined exten‐
33       sions.
34
35       The argument nsops is the number of such structures in the array.
36
37       Each structure, sembuf, includes the following members:
38
39             ┌───────────────┬───────────────┬──────────────────────────┐
40Member Type   Member Name   Description        
41             ├───────────────┼───────────────┼──────────────────────────┤
42unsigned short sem_num       │Semaphore number.         │
43short          sem_op        │Semaphore operation.      │
44short          sem_flg       │Operation flags.          │
45             └───────────────┴───────────────┴──────────────────────────┘
46       Each semaphore operation specified by sem_op is performed on the corre‐
47       sponding semaphore specified by semid and sem_num.
48
49       The variable sem_op specifies one of three semaphore operations:
50
51        1. If  sem_op  is a negative integer and the calling process has alter
52           permission, one of the following shall occur:
53
54            *  If semval(see <sys/sem.h>) is greater  than  or  equal  to  the
55               absolute  value of sem_op, the absolute value of sem_op is sub‐
56               tracted from semval.  Also, if (sem_flg &SEM_UNDO) is non-zero,
57               the absolute value of sem_op shall be added to the semadj value
58               of the calling process for the specified semaphore.
59
60            *  If semval is  less  than  the  absolute  value  of  sem_op  and
61               (sem_flg &IPC_NOWAIT) is non-zero, semop() shall return immedi‐
62               ately.
63
64            *  If semval is  less  than  the  absolute  value  of  sem_op  and
65               (sem_flg &IPC_NOWAIT) is 0, semop() shall increment the semncnt
66               associated with the specified semaphore and  suspend  execution
67               of  the  calling  thread  until one of the following conditions
68               occurs:
69
70               --  The value of semval becomes greater than or  equal  to  the
71                   absolute  value  of sem_op.  When this occurs, the value of
72                   semncnt associated with the specified  semaphore  shall  be
73                   decremented,  the  absolute  value  of sem_op shall be sub‐
74                   tracted from semval and, if  (sem_flg  &SEM_UNDO)  is  non-
75                   zero,  the  absolute  value of sem_op shall be added to the
76                   semadj value of the calling process for the specified sema‐
77                   phore.
78
79               --  The  semid  for which the calling thread is awaiting action
80                   is removed from the system. When this occurs,  errno  shall
81                   be set to [EIDRM] and −1 shall be returned.
82
83               --  The  calling thread receives a signal that is to be caught.
84                   When this occurs, the value of semncnt associated with  the
85                   specified  semaphore  shall be decremented, and the calling
86                   thread shall resume execution in the manner  prescribed  in
87                   sigaction().
88
89        2. If  sem_op  is a positive integer and the calling process has alter
90           permission, the value of sem_op shall be added to  semval  and,  if
91           (sem_flg  &SEM_UNDO) is non-zero, the value of sem_op shall be sub‐
92           tracted from the semadj value of the calling process for the speci‐
93           fied semaphore.
94
95        3. If  sem_op is 0 and the calling process has read permission, one of
96           the following shall occur:
97
98            *  If semval is 0, semop() shall return immediately.
99
100            *  If semval is non-zero and (sem_flg  &IPC_NOWAIT)  is  non-zero,
101               semop() shall return immediately.
102
103            *  If  semval  is non-zero and (sem_flg &IPC_NOWAIT) is 0, semop()
104               shall increment the semzcnt associated with the specified sema‐
105               phore  and suspend execution of the calling thread until one of
106               the following occurs:
107
108               --  The value of semval becomes 0, at which time the  value  of
109                   semzcnt  associated  with  the specified semaphore shall be
110                   decremented.
111
112               --  The semid for which the calling thread is  awaiting  action
113                   is  removed  from the system. When this occurs, errno shall
114                   be set to [EIDRM] and −1 shall be returned.
115
116               --  The calling thread receives a signal that is to be  caught.
117                   When  this occurs, the value of semzcnt associated with the
118                   specified semaphore shall be decremented, and  the  calling
119                   thread  shall  resume execution in the manner prescribed in
120                   sigaction().
121
122       Upon successful completion, the value  of  sempid  for  each  semaphore
123       specified  in  the array pointed to by sops shall be set to the process
124       ID of the calling process. Also, the sem_otime timestamp shall  be  set
125       to  the  current  time,  as  described  in  Section  2.7.1, IPC General
126       Description.
127

RETURN VALUE

129       Upon successful completion, semop() shall return 0; otherwise, it shall
130       return −1 and set errno to indicate the error.
131

ERRORS

133       The semop() function shall fail if:
134
135       E2BIG  The value of nsops is greater than the system-imposed maximum.
136
137       EACCES Operation  permission is denied to the calling process; see Sec‐
138              tion 2.7, XSI Interprocess Communication.
139
140       EAGAIN The operation would result in suspension of the calling  process
141              but (sem_flg &IPC_NOWAIT) is non-zero.
142
143       EFBIG  The  value  of sem_num is greater than or equal to the number of
144              semaphores in the set associated with semid.
145
146       EIDRM  The semaphore identifier semid is removed from the system.
147
148       EINTR  The semop() function was interrupted by a signal.
149
150       EINVAL The value of semid is not a valid semaphore identifier,  or  the
151              number  of  individual  semaphores for which the calling process
152              requests a SEM_UNDO would exceed the system-imposed limit.
153
154       ENOSPC The limit on the number of  individual  processes  requesting  a
155              SEM_UNDO would be exceeded.
156
157       ERANGE An operation would cause a semval to overflow the system-imposed
158              limit, or an operation would cause a semadj  value  to  overflow
159              the system-imposed limit.
160
161       The following sections are informative.
162

EXAMPLES

164   Setting Values in Semaphores
165       The  following example sets the values of the two semaphores associated
166       with the semid identifier to the values contained in the sb array.
167
168           #include <sys/sem.h>
169           ...
170           int semid;
171           struct sembuf sb[2];
172           int nsops = 2;
173           int result;
174
175           /* Code to initialize semid. */
176           ...
177
178           /* Adjust value of semaphore in the semaphore array semid. */
179           sb[0].sem_num = 0;
180           sb[0].sem_op = -1;
181           sb[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
182           sb[1].sem_num = 1;
183           sb[1].sem_op = 1;
184           sb[1].sem_flg = 0;
185
186           result = semop(semid, sb, nsops);
187
188   Creating a Semaphore Identifier
189       The following example gets a unique  semaphore  key  using  the  ftok()
190       function,  then  gets a semaphore ID associated with that key using the
191       semget() function (the first call also tests to make sure the semaphore
192       exists).   If  the semaphore does not exist, the program creates it, as
193       shown by the second call to semget().  In creating  the  semaphore  for
194       the  queuing process, the program attempts to create one semaphore with
195       read/write permission for all. It also uses the  IPC_EXCL  flag,  which
196       forces semget() to fail if the semaphore already exists.
197
198       After  creating  the  semaphore, the program uses calls to semctl() and
199       semop() to initialize it to the values in the sbuf array. The number of
200       processes  that  can  execute concurrently without queuing is initially
201       set to 2. The final call to semget()  creates  a  semaphore  identifier
202       that can be used later in the program.
203
204       Processes that obtain semid without creating it check that sem_otime is
205       non-zero, to ensure that the creating process has completed the semop()
206       initialization.
207
208       The  final call to semop() acquires the semaphore and waits until it is
209       free; the SEM_UNDO option  releases  the  semaphore  when  the  process
210       exits,  waiting until there are less than two processes running concur‐
211       rently.
212
213           #include <stdio.h>
214           #include <sys/sem.h>
215           #include <sys/stat.h>
216           #include <errno.h>
217           #include <stdlib.h>
218           ...
219           key_t semkey;
220           int semid;
221           struct sembuf sbuf;
222           union semun {
223               int val;
224               struct semid_ds *buf;
225               unsigned short *array;
226           } arg;
227           struct semid_ds ds;
228           ...
229           /* Get unique key for semaphore. */
230           if ((semkey = ftok("/tmp", 'a')) == (key_t) -1) {
231               perror("IPC error: ftok"); exit(1);
232           }
233
234           /* Get semaphore ID associated with this key. */
235           if ((semid = semget(semkey, 0, 0)) == -1) {
236
237               /* Semaphore does not exist - Create. */
238               if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR |
239                   S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1)
240               {
241                   /* Initialize the semaphore. */
242                   arg.val = 0;
243                   sbuf.sem_num = 0;
244                   sbuf.sem_op = 2;  /* This is the number of runs without queuing. */
245                   sbuf.sem_flg = 0;
246                   if (semctl(semid, 0, SETVAL, arg) == -1
247                       || semop(semid, &sbuf, 1) == -1) {
248                       perror("IPC error: semop"); exit(1);
249                   }
250               }
251               else if (errno == EEXIST) {
252                   if ((semid = semget(semkey, 0, 0)) == -1) {
253                       perror("IPC error 1: semget"); exit(1);
254                   }
255                   goto check_init;
256               }
257               else {
258                   perror("IPC error 2: semget"); exit(1);
259               }
260           }
261           else
262           {
263               /* Check that semid has completed initialization. */
264               /* An application can use a retry loop at this point rather than
265                  exiting. */
266               check_init:
267               arg.buf = &ds;
268               if (semctl(semid, 0, IPC_STAT, arg) < 0) {
269                   perror("IPC error 3: semctl"); exit(1);
270               }
271               if (ds.sem_otime == 0) {
272                   perror("IPC error 4: semctl"); exit(1);
273               }
274           }
275           ...
276           sbuf.sem_num = 0;
277           sbuf.sem_op = -1;
278           sbuf.sem_flg = SEM_UNDO;
279           if (semop(semid, &sbuf, 1) == -1) {
280               perror("IPC Error: semop"); exit(1);
281           }
282

APPLICATION USAGE

284       The POSIX Realtime Extension defines alternative interfaces for  inter‐
285       process  communication.  Application  developers  who  need  to use IPC
286       should design their applications so that modules using the IPC routines
287       described  in Section 2.7, XSI Interprocess Communication can be easily
288       modified to use the alternative interfaces.
289

RATIONALE

291       None.
292

FUTURE DIRECTIONS

294       None.
295

SEE ALSO

297       Section 2.7, XSI Interprocess  Communication,  Section  2.8,  Realtime,
298       exec,  exit(),  fork(), semctl(), semget(), sem_close(), sem_destroy(),
299       sem_getvalue(),  sem_init(),  sem_open(),  sem_post(),   sem_trywait(),
300       sem_unlink()
301
302       The  Base  Definitions volume of POSIX.1‐2008, Section 4.16, Semaphore,
303       <sys_ipc.h>, <sys_sem.h>, <sys_types.h>
304
306       Portions of this text are reprinted and reproduced in  electronic  form
307       from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology
308       -- Portable Operating System Interface (POSIX),  The  Open  Group  Base
309       Specifications Issue 7, Copyright (C) 2013 by the Institute of Electri‐
310       cal and Electronics Engineers,  Inc  and  The  Open  Group.   (This  is
311       POSIX.1-2008  with  the  2013  Technical Corrigendum 1 applied.) In the
312       event of any discrepancy between this version and the original IEEE and
313       The  Open Group Standard, the original IEEE and The Open Group Standard
314       is the referee document. The original Standard can be  obtained  online
315       at http://www.unix.org/online.html .
316
317       Any  typographical  or  formatting  errors that appear in this page are
318       most likely to have been introduced during the conversion of the source
319       files  to  man page format. To report such errors, see https://www.ker
320       nel.org/doc/man-pages/reporting_bugs.html .
321
322
323
324IEEE/The Open Group                  2013                            SEMOP(3P)
Impressum