1SEMGET(2) Linux Programmer's Manual SEMGET(2)
2
3
4
6 semget - get a System V semaphore set identifier
7
9 #include <sys/types.h>
10 #include <sys/ipc.h>
11 #include <sys/sem.h>
12
13 int semget(key_t key, int nsems, int semflg);
14
16 The semget() system call returns the System V semaphore set identifier
17 associated with the argument key. It may be used either to obtain the
18 identifier of a previously created semaphore set (when semflg is zero
19 and key does not have the value IPC_PRIVATE), or to create a new set.
20
21 A new set of nsems semaphores is created if key has the value IPC_PRI‐
22 VATE or if no existing semaphore set is associated with key and
23 IPC_CREAT is specified in semflg.
24
25 If semflg specifies both IPC_CREAT and IPC_EXCL and a semaphore set
26 already exists for key, then semget() fails with errno set to EEXIST.
27 (This is analogous to the effect of the combination O_CREAT | O_EXCL
28 for open(2).)
29
30 Upon creation, the least significant 9 bits of the argument semflg
31 define the permissions (for owner, group and others) for the semaphore
32 set. These bits have the same format, and the same meaning, as the
33 mode argument of open(2) (though the execute permissions are not mean‐
34 ingful for semaphores, and write permissions mean permission to alter
35 semaphore values).
36
37 When creating a new semaphore set, semget() initializes the set's asso‐
38 ciated data structure, semid_ds (see semctl(2)), as follows:
39
40 · sem_perm.cuid and sem_perm.uid are set to the effective user ID of
41 the calling process.
42
43 · sem_perm.cgid and sem_perm.gid are set to the effective group ID of
44 the calling process.
45
46 · The least significant 9 bits of sem_perm.mode are set to the least
47 significant 9 bits of semflg.
48
49 · sem_nsems is set to the value of nsems.
50
51 · sem_otime is set to 0.
52
53 · sem_ctime is set to the current time.
54
55 The argument nsems can be 0 (a don't care) when a semaphore set is not
56 being created. Otherwise, nsems must be greater than 0 and less than
57 or equal to the maximum number of semaphores per semaphore set
58 (SEMMSL).
59
60 If the semaphore set already exists, the permissions are verified.
61
63 If successful, the return value will be the semaphore set identifier (a
64 nonnegative integer), otherwise, -1 is returned, with errno indicating
65 the error.
66
68 On failure, errno will be set to one of the following:
69
70 EACCES A semaphore set exists for key, but the calling process does not
71 have permission to access the set, and does not have the
72 CAP_IPC_OWNER capability in the user namespace that governs its
73 IPC namespace.
74
75 EEXIST IPC_CREAT and IPC_EXCL were specified in semflg, but a semaphore
76 set already exists for key.
77
78 EINVAL nsems is less than 0 or greater than the limit on the number of
79 semaphores per semaphore set (SEMMSL).
80
81 EINVAL A semaphore set corresponding to key already exists, but nsems
82 is larger than the number of semaphores in that set.
83
84 ENOENT No semaphore set exists for key and semflg did not specify
85 IPC_CREAT.
86
87 ENOMEM A semaphore set has to be created but the system does not have
88 enough memory for the new data structure.
89
90 ENOSPC A semaphore set has to be created but the system limit for the
91 maximum number of semaphore sets (SEMMNI), or the system wide
92 maximum number of semaphores (SEMMNS), would be exceeded.
93
95 SVr4, POSIX.1-2001.
96
98 The inclusion of <sys/types.h> and <sys/ipc.h> isn't required on Linux
99 or by any version of POSIX. However, some old implementations required
100 the inclusion of these header files, and the SVID also documented their
101 inclusion. Applications intended to be portable to such old systems
102 may need to include these header files.
103
104 IPC_PRIVATE isn't a flag field but a key_t type. If this special value
105 is used for key, the system call ignores all but the least significant
106 9 bits of semflg and creates a new semaphore set (on success).
107
108 Semaphore initialization
109 The values of the semaphores in a newly created set are indeterminate.
110 (POSIX.1-2001 and POSIX.1-2008 are explicit on this point, although
111 POSIX.1-2008 notes that a future version of the standard may require an
112 implementation to initialize the semaphores to 0.) Although Linux,
113 like many other implementations, initializes the semaphore values to 0,
114 a portable application cannot rely on this: it should explicitly ini‐
115 tialize the semaphores to the desired values.
116
117 Initialization can be done using semctl(2) SETVAL or SETALL operation.
118 Where multiple peers do not know who will be the first to initialize
119 the set, checking for a nonzero sem_otime in the associated data struc‐
120 ture retrieved by a semctl(2) IPC_STAT operation can be used to avoid
121 races.
122
123 Semaphore limits
124 The following limits on semaphore set resources affect the semget()
125 call:
126
127 SEMMNI System-wide limit on the number of semaphore sets. On Linux
128 systems before version 3.19, the default value for this limit
129 was 128. Since Linux 3.19, the default value is 32,000. On
130 Linux, this limit can be read and modified via the fourth field
131 of /proc/sys/kernel/sem.
132
133 SEMMSL Maximum number of semaphores per semaphore ID. On Linux systems
134 before version 3.19, the default value for this limit was 250.
135 Since Linux 3.19, the default value is 32,000. On Linux, this
136 limit can be read and modified via the first field of
137 /proc/sys/kernel/sem.
138
139 SEMMNS System-wide limit on the number of semaphores: policy dependent
140 (on Linux, this limit can be read and modified via the second
141 field of /proc/sys/kernel/sem). Note that the number of sema‐
142 phores system-wide is also limited by the product of SEMMSL and
143 SEMMNI.
144
146 The name choice IPC_PRIVATE was perhaps unfortunate, IPC_NEW would more
147 clearly show its function.
148
150 The program shown below uses semget() to create a new semaphore set or
151 retrieve the ID of an existing set. It generates the key for semget()
152 using ftok(3). The first two command-line arguments are used as the
153 pathname and proj_id arguments for ftok(3). The third command-line
154 argument is an integer that specifies the nsems argument for semget().
155 Command-line options can be used to specify the IPC_CREAT (-c) and
156 IPC_EXCL (-x) flags for the call to semget(). The usage of this pro‐
157 gram is demonstrated below.
158
159 We first create two files that will be used to generate keys using
160 ftok(3), create two semaphore sets using those files, and then list the
161 sets using ipcs(1):
162
163 $ touch mykey mykey2
164 $ ./t_semget -c mykey p 1
165 ID = 9
166 $ ./t_semget -c mykey2 p 2
167 ID = 10
168 $ ipcs -s
169
170 ------ Semaphore Arrays --------
171 key semid owner perms nsems
172 0x7004136d 9 mtk 600 1
173 0x70041368 10 mtk 600 2
174
175 Next, we demonstrate that when semctl(2) is given the same key (as gen‐
176 erated by the same arguments to ftok(3)), it returns the ID of the
177 already existing semaphore set:
178
179 $ ./t_semget -c mykey p 1
180 ID = 9
181
182 Finally, we demonstrate the kind of collision that can occur when
183 ftok(3) is given different pathname arguments that have the same inode
184 number:
185
186 $ ln mykey link
187 $ ls -i1 link mykey
188 2233197 link
189 2233197 mykey
190 $ ./t_semget link p 1 # Generates same key as 'mykey'
191 ID = 9
192
193 Program source
194
195 /* t_semget.c
196
197 Licensed under GNU General Public License v2 or later.
198 */
199 #include <sys/types.h>
200 #include <sys/ipc.h>
201 #include <sys/sem.h>
202 #include <sys/stat.h>
203 #include <stdio.h>
204 #include <stdlib.h>
205 #include <unistd.h>
206
207 static void
208 usage(const char *pname)
209 {
210 fprintf(stderr, "Usage: %s [-cx] pathname proj-id num-sems\n",
211 pname);
212 fprintf(stderr, " -c Use IPC_CREAT flag\n");
213 fprintf(stderr, " -x Use IPC_EXCL flag\n");
214 exit(EXIT_FAILURE);
215 }
216
217 int
218 main(int argc, char *argv[])
219 {
220 int semid, nsems, flags, opt;
221 key_t key;
222
223 flags = 0;
224 while ((opt = getopt(argc, argv, "cx")) != -1) {
225 switch (opt) {
226 case 'c': flags |= IPC_CREAT; break;
227 case 'x': flags |= IPC_EXCL; break;
228 default: usage(argv[0]);
229 }
230 }
231
232 if (argc != optind + 3)
233 usage(argv[0]);
234
235 key = ftok(argv[optind], argv[optind + 1][0]);
236 if (key == -1) {
237 perror("ftok");
238 exit(EXIT_FAILURE);
239 }
240
241 nsems = atoi(argv[optind + 2]);
242
243 semid = semget(key, nsems, flags | 0600);
244 if (semid == -1) {
245 perror("semget");
246 exit(EXIT_FAILURE);
247 }
248
249 printf("ID = %d\n", semid);
250
251 exit(EXIT_SUCCESS);
252 }
253
255 semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7),
256 sysvipc(7)
257
259 This page is part of release 5.07 of the Linux man-pages project. A
260 description of the project, information about reporting bugs, and the
261 latest version of this page, can be found at
262 https://www.kernel.org/doc/man-pages/.
263
264
265
266Linux 2020-04-11 SEMGET(2)