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