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
121 Interface Attribute Value
128 T} Thread safety MT-Safe
135 The (somewhat trivial) program shown below operates on an
137 The program expects two command-line arguments.
138 The first argument specifies a seconds value that is used to
139 set an alarm timer to generate a
142 This handler performs a
144 to increment the semaphore that is being waited on in
147 .BR sem_timedwait ().
148 The second command-line argument specifies the length
149 of the timeout, in seconds, for
150 .BR sem_timedwait ().
151 The following shows what happens on two different runs of the program:
155 .RB "$" " ./a.out 2 3"
156 About to call sem_timedwait()
157 sem_post() from handler
158 sem_timedwait() succeeded
159 .RB "$" " ./a.out 2 1"
160 About to call sem_timedwait()
161 sem_timedwait() timed out
166 .\" SRC BEGIN (sem_wait.c)
169 #include <semaphore.h>
180 #define handle_error(msg) \e
181 do { perror(msg); exit(EXIT_FAILURE); } while (0)
186 write(STDOUT_FILENO, "sem_post() from handler\en", 24);
187 if (sem_post(&sem) == \-1) {
188 write(STDERR_FILENO, "sem_post() failed\en", 18);
194 main(int argc, char *argv[])
201 fprintf(stderr, "Usage: %s <alarm\-secs> <wait\-secs>\en",
206 if (sem_init(&sem, 0, 0) == \-1)
207 handle_error("sem_init");
209 /* Establish SIGALRM handler; set alarm timer using argv[1]. */
211 sa.sa_handler = handler;
212 sigemptyset(&sa.sa_mask);
214 if (sigaction(SIGALRM, &sa, NULL) == \-1)
215 handle_error("sigaction");
217 alarm(atoi(argv[1]));
219 /* Calculate relative interval as current time plus
220 number of seconds given argv[2]. */
222 if (clock_gettime(CLOCK_REALTIME, &ts) == \-1)
223 handle_error("clock_gettime");
225 ts.tv_sec += atoi(argv[2]);
227 printf("%s() about to call sem_timedwait()\en", __func__);
228 while ((s = sem_timedwait(&sem, &ts)) == \-1 && errno == EINTR)
229 continue; /* Restart if interrupted by handler. */
231 /* Check what happened. */
234 if (errno == ETIMEDOUT)
235 printf("sem_timedwait() timed out\en");
237 perror("sem_timedwait");
239 printf("sem_timedwait() succeeded\en");
241 exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
246 .BR clock_gettime (2),
247 .BR sem_getvalue (3),
250 .BR sem_overview (7),