2 .\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
6 .TH sem_wait 3 (date) "Linux man-pages (unreleased)"
8 sem_wait, sem_timedwait, sem_trywait \- lock a semaphore
11 .RI ( libpthread ", " \-lpthread )
14 .B #include <semaphore.h>
16 .BI "int sem_wait(sem_t *" sem );
17 .BI "int sem_trywait(sem_t *" sem );
18 .BI "int sem_timedwait(sem_t *restrict " sem ,
19 .BI " const struct timespec *restrict " abs_timeout );
23 Feature Test Macro Requirements for glibc (see
24 .BR feature_test_macros (7)):
29 _POSIX_C_SOURCE >= 200112L
33 decrements (locks) the semaphore pointed to by
35 If the semaphore's value is greater than zero,
36 then the decrement proceeds, and the function returns, immediately.
37 If the semaphore currently has the value zero,
38 then the call blocks until either it becomes possible to perform
39 the decrement (i.e., the semaphore value rises above zero),
40 or a signal handler interrupts the call.
45 except that if the decrement cannot be immediately performed,
46 then call returns an error
57 specifies a limit on the amount of time that the call
58 should block if the decrement cannot be immediately performed.
63 structure that specifies an absolute timeout
64 in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
66 If the timeout has already expired by the time of the call,
67 and the semaphore could not be locked immediately,
70 fails with a timeout error
75 If the operation can be performed immediately, then
77 never fails with a timeout error, regardless of the value of
79 Furthermore, the validity of
81 is not checked in this case.
83 All of these functions return 0 on success;
84 on error, the value of the semaphore is left unchanged,
87 is set to indicate the error.
92 The operation could not be performed without blocking (i.e., the
93 semaphore currently has the value zero).
96 The call was interrupted by a signal handler; see
101 is not a valid semaphore.
104 .RB ( sem_timedwait ())
106 .I abs_timeout.tv_nsecs
107 is less than 0, or greater than or equal to 1000 million.
110 .RB ( sem_timedwait ())
111 The call timed out before the semaphore could be locked.
112 .\" POSIX.1-2001 also allows EDEADLK -- "A deadlock condition
113 .\" was detected", but this does not occur on Linux(?).
115 For an explanation of the terms used in this section, see
123 Interface Attribute Value
128 T} Thread safety MT-Safe
134 POSIX.1-2001, POSIX.1-2008.
136 The (somewhat trivial) program shown below operates on an
138 The program expects two command-line arguments.
139 The first argument specifies a seconds value that is used to
140 set an alarm timer to generate a
143 This handler performs a
145 to increment the semaphore that is being waited on in
148 .BR sem_timedwait ().
149 The second command-line argument specifies the length
150 of the timeout, in seconds, for
151 .BR sem_timedwait ().
152 The following shows what happens on two different runs of the program:
156 .RB "$" " ./a.out 2 3"
157 About to call sem_timedwait()
158 sem_post() from handler
159 sem_timedwait() succeeded
160 .RB "$" " ./a.out 2 1"
161 About to call sem_timedwait()
162 sem_timedwait() timed out
167 .\" SRC BEGIN (sem_wait.c)
170 #include <semaphore.h>
181 #define handle_error(msg) \e
182 do { perror(msg); exit(EXIT_FAILURE); } while (0)
187 write(STDOUT_FILENO, "sem_post() from handler\en", 24);
188 if (sem_post(&sem) == \-1) {
189 write(STDERR_FILENO, "sem_post() failed\en", 18);
195 main(int argc, char *argv[])
202 fprintf(stderr, "Usage: %s <alarm\-secs> <wait\-secs>\en",
207 if (sem_init(&sem, 0, 0) == \-1)
208 handle_error("sem_init");
210 /* Establish SIGALRM handler; set alarm timer using argv[1]. */
212 sa.sa_handler = handler;
213 sigemptyset(&sa.sa_mask);
215 if (sigaction(SIGALRM, &sa, NULL) == \-1)
216 handle_error("sigaction");
218 alarm(atoi(argv[1]));
220 /* Calculate relative interval as current time plus
221 number of seconds given argv[2]. */
223 if (clock_gettime(CLOCK_REALTIME, &ts) == \-1)
224 handle_error("clock_gettime");
226 ts.tv_sec += atoi(argv[2]);
228 printf("%s() about to call sem_timedwait()\en", __func__);
229 while ((s = sem_timedwait(&sem, &ts)) == \-1 && errno == EINTR)
230 continue; /* Restart if interrupted by handler. */
232 /* Check what happened. */
235 if (errno == ETIMEDOUT)
236 printf("sem_timedwait() timed out\en");
238 perror("sem_timedwait");
240 printf("sem_timedwait() succeeded\en");
242 exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
247 .BR clock_gettime (2),
248 .BR sem_getvalue (3),
251 .BR sem_overview (7),