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