1SEMOP(3P) POSIX Programmer's Manual SEMOP(3P)
2
3
4
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
12 semop - XSI semaphore operations
13
15 #include <sys/sem.h>
16
17 int semop(int semid, struct sembuf *sops, size_t nsops);
18
19
21 The semop() function operates on XSI semaphores (see the Base Defini‐
22 tions volume of IEEE Std 1003.1-2001, Section 4.15, Semaphore). It is
23 unspecified whether this function interoperates with the realtime
24 interprocess communication facilities defined in Realtime .
25
26 The semop() function shall perform atomically a user-defined array of
27 semaphore operations on the set of semaphores associated with the sema‐
28 phore 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 Member Type Member Name Description
40 short sem_num Semaphore number.
41 short sem_op Semaphore operation.
42 short sem_flg Operation flags.
43
44 Each semaphore operation specified by sem_op is performed on the corre‐
45 sponding semaphore specified by semid and sem_num.
46
47 The variable sem_op specifies one of three semaphore operations:
48
49 1. If sem_op is a negative integer and the calling process has alter
50 permission, one of the following shall occur:
51
52 * If semval(see <sys/sem.h>) is greater than or equal to the abso‐
53 lute value of sem_op, the absolute value of sem_op is subtracted
54 from semval. Also, if (sem_flg &SEM_UNDO) is non-zero, the abso‐
55 lute value of sem_op shall be added to the calling process'
56 semadj value for the specified semaphore.
57
58 * If semval is less than the absolute value of sem_op and (sem_flg
59 &IPC_NOWAIT) is non-zero, semop() shall return immediately.
60
61 * If semval is less than the absolute value of sem_op and (sem_flg
62 &IPC_NOWAIT) is 0, semop() shall increment the semncnt associ‐
63 ated with the specified semaphore and suspend execution of the
64 calling thread until one of the following conditions occurs:
65
66 * The value of semval becomes greater than or equal to the
67 absolute value of sem_op. When this occurs, the value of sem‐
68 ncnt associated with the specified semaphore shall be decre‐
69 mented, the absolute value of sem_op shall be subtracted from
70 semval and, if (sem_flg &SEM_UNDO) is non-zero, the absolute
71 value of sem_op shall be added to the calling process' semadj
72 value for the specified semaphore.
73
74 * The semid for which the calling thread is awaiting action is
75 removed from the system. When this occurs, errno shall be set
76 equal to [EIDRM] and -1 shall be returned.
77
78 * The calling thread receives a signal that is to be caught.
79 When this occurs, the value of semncnt associated with the
80 specified semaphore shall be decremented, and the calling
81 thread shall resume execution in the manner prescribed in
82 sigaction().
83
84 2. If sem_op is a positive integer and the calling process has alter
85 permission, the value of sem_op shall be added to semval and, if
86 (sem_flg &SEM_UNDO) is non-zero, the value of sem_op shall be sub‐
87 tracted from the calling process' semadj value for the specified
88 semaphore.
89
90 3. If sem_op is 0 and the calling process has read permission, one of
91 the following shall occur:
92
93 * If semval is 0, semop() shall return immediately.
94
95 * If semval is non-zero and (sem_flg &IPC_NOWAIT) is non-zero,
96 semop() shall return immediately.
97
98 * If semval is non-zero and (sem_flg &IPC_NOWAIT) is 0, semop()
99 shall increment the semzcnt associated with the specified sema‐
100 phore and suspend execution of the calling thread until one of
101 the following occurs:
102
103 * The value of semval becomes 0, at which time the value of
104 semzcnt associated with the specified semaphore shall be
105 decremented.
106
107 * The semid for which the calling thread is awaiting action is
108 removed from the system. When this occurs, errno shall be set
109 equal to [EIDRM] and -1 shall be returned.
110
111 * The calling thread receives a signal that is to be caught.
112 When this occurs, the value of semzcnt associated with the
113 specified semaphore shall be decremented, and the calling
114 thread shall resume execution in the manner prescribed in
115 sigaction().
116
117 Upon successful completion, the value of sempid for each semaphore
118 specified in the array pointed to by sops shall be set equal to the
119 process ID of the calling process.
120
122 Upon successful completion, semop() shall return 0; otherwise, it shall
123 return -1 and set errno to indicate the error.
124
126 The semop() function shall fail if:
127
128 E2BIG The value of nsops is greater than the system-imposed maximum.
129
130 EACCES Operation permission is denied to the calling process; see XSI
131 Interprocess Communication .
132
133 EAGAIN The operation would result in suspension of the calling process
134 but (sem_flg &IPC_NOWAIT) is non-zero.
135
136 EFBIG The value of sem_num is less than 0 or greater than or equal to
137 the number of semaphores in the set associated with semid.
138
139 EIDRM The semaphore identifier semid is removed from the system.
140
141 EINTR The semop() function was interrupted by a signal.
142
143 EINVAL The value of semid is not a valid semaphore identifier, or the
144 number of individual semaphores for which the calling process
145 requests a SEM_UNDO would exceed the system-imposed limit.
146
147 ENOSPC The limit on the number of individual processes requesting a
148 SEM_UNDO would be exceeded.
149
150 ERANGE An operation would cause a semval to overflow the system-imposed
151 limit, or an operation would cause a semadj value to overflow
152 the system-imposed limit.
153
154
155 The following sections are informative.
156
158 Setting Values in Semaphores
159 The following example sets the values of the two semaphores associated
160 with the semid identifier to the values contained in the sb array.
161
162
163 #include <sys/sem.h>
164 ...
165 int semid;
166 struct sembuf sb[2];
167 int nsops = 2;
168 int result;
169
170
171 /* Adjust value of semaphore in the semaphore array semid. */
172 sb[0].sem_num = 0;
173 sb[0].sem_op = -1;
174 sb[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
175 sb[1].sem_num = 1;
176 sb[1].sem_op = 1;
177 sb[1].sem_flg = 0;
178
179
180 result = semop(semid, sb, nsops);
181
182 Creating a Semaphore Identifier
183 The following example gets a unique semaphore key using the ftok()
184 function, then gets a semaphore ID associated with that key using the
185 semget() function (the first call also tests to make sure the semaphore
186 exists). If the semaphore does not exist, the program creates it, as
187 shown by the second call to semget(). In creating the semaphore for the
188 queuing process, the program attempts to create one semaphore with
189 read/write permission for all. It also uses the IPC_EXCL flag, which
190 forces semget() to fail if the semaphore already exists.
191
192 After creating the semaphore, the program uses a call to semop() to
193 initialize it to the values in the sbuf array. The number of processes
194 that can execute concurrently without queuing is initially set to 2.
195 The final call to semget() creates a semaphore identifier that can be
196 used later in the program.
197
198 The final call to semop() acquires the semaphore and waits until it is
199 free; the SEM_UNDO option releases the semaphore when the process
200 exits, waiting until there are less than two processes running concur‐
201 rently.
202
203
204 #include <sys/types.h>
205 #include <stdio.h>
206 #include <sys/ipc.h>
207 #include <sys/sem.h>
208 #include <sys/stat.h>
209 #include <errno.h>
210 #include <unistd.h>
211 #include <stdlib.h>
212 #include <pwd.h>
213 #include <fcntl.h>
214 #include <limits.h>
215 ...
216 key_t semkey;
217 int semid, pfd, fv;
218 struct sembuf sbuf;
219 char *lgn;
220 char filename[PATH_MAX+1];
221 struct stat outstat;
222 struct passwd *pw;
223 ...
224 /* Get unique key for semaphore. */
225 if ((semkey = ftok("/tmp", 'a')) == (key_t) -1) {
226 perror("IPC error: ftok"); exit(1);
227 }
228
229
230 /* Get semaphore ID associated with this key. */
231 if ((semid = semget(semkey, 0, 0)) == -1) {
232
233
234 /* Semaphore does not exist - Create. */
235 if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR |
236 S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1)
237 {
238 /* Initialize the semaphore. */
239 sbuf.sem_num = 0;
240 sbuf.sem_op = 2; /* This is the number of runs without queuing. */
241 sbuf.sem_flg = 0;
242 if (semop(semid, &sbuf, 1) == -1) {
243 perror("IPC error: semop"); exit(1);
244 }
245 }
246 else if (errno == EEXIST) {
247 if ((semid = semget(semkey, 0, 0)) == -1) {
248 perror("IPC error 1: semget"); exit(1);
249 }
250 }
251 else {
252 perror("IPC error 2: semget"); exit(1);
253 }
254 }
255 ...
256 sbuf.sem_num = 0;
257 sbuf.sem_op = -1;
258 sbuf.sem_flg = SEM_UNDO;
259 if (semop(semid, &sbuf, 1) == -1) {
260 perror("IPC Error: semop"); exit(1);
261 }
262
264 The POSIX Realtime Extension defines alternative interfaces for inter‐
265 process communication. Application developers who need to use IPC
266 should design their applications so that modules using the IPC routines
267 described in XSI Interprocess Communication can be easily modified to
268 use the alternative interfaces.
269
271 None.
272
274 None.
275
277 XSI Interprocess Communication, Realtime, exec() , exit(), fork(), sem‐
278 ctl(), semget(), sem_close(), sem_destroy(), sem_getvalue(),
279 sem_init(), sem_open(), sem_post(), sem_unlink(), sem_wait(), the Base
280 Definitions volume of IEEE Std 1003.1-2001, <sys/ipc.h>, <sys/sem.h>,
281 <sys/types.h>
282
284 Portions of this text are reprinted and reproduced in electronic form
285 from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
286 -- Portable Operating System Interface (POSIX), The Open Group Base
287 Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of
288 Electrical and Electronics Engineers, Inc and The Open Group. In the
289 event of any discrepancy between this version and the original IEEE and
290 The Open Group Standard, the original IEEE and The Open Group Standard
291 is the referee document. The original Standard can be obtained online
292 at http://www.opengroup.org/unix/online.html .
293
294
295
296IEEE/The Open Group 2003 SEMOP(3P)