1sem_wait(3)                Library Functions Manual                sem_wait(3)
2
3
4

NAME

6       sem_wait, sem_timedwait, sem_trywait - lock a semaphore
7

LIBRARY

9       POSIX threads library (libpthread, -lpthread)
10

SYNOPSIS

12       #include <semaphore.h>
13
14       int sem_wait(sem_t *sem);
15       int sem_trywait(sem_t *sem);
16       int sem_timedwait(sem_t *restrict sem,
17                         const struct timespec *restrict abs_timeout);
18
19   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
20
21       sem_timedwait():
22           _POSIX_C_SOURCE >= 200112L
23

DESCRIPTION

25       sem_wait()  decrements (locks) the semaphore pointed to by sem.  If the
26       semaphore's value is greater than zero, then  the  decrement  proceeds,
27       and  the function returns, immediately.  If the semaphore currently has
28       the value zero, then the call blocks until either it  becomes  possible
29       to  perform the decrement (i.e., the semaphore value rises above zero),
30       or a signal handler interrupts the call.
31
32       sem_trywait() is the same as sem_wait(), except that if  the  decrement
33       cannot  be immediately performed, then call returns an error (errno set
34       to EAGAIN) instead of blocking.
35
36       sem_timedwait() is the same  as  sem_wait(),  except  that  abs_timeout
37       specifies  a  limit on the amount of time that the call should block if
38       the decrement cannot be immediately performed.  The  abs_timeout  argu‐
39       ment points to a timespec(3) structure that specifies an absolute time‐
40       out in seconds and nanoseconds since  the  Epoch,  1970-01-01  00:00:00
41       +0000 (UTC).
42
43       If  the  timeout  has  already expired by the time of the call, and the
44       semaphore could not be locked immediately, then  sem_timedwait()  fails
45       with a timeout error (errno set to ETIMEDOUT).
46
47       If  the  operation  can  be performed immediately, then sem_timedwait()
48       never fails with a timeout error, regardless of the value of  abs_time‐
49       out.   Furthermore,  the validity of abs_timeout is not checked in this
50       case.
51

RETURN VALUE

53       All of these functions return 0 on success; on error, the value of  the
54       semaphore  is left unchanged, -1 is returned, and errno is set to indi‐
55       cate the error.
56

ERRORS

58       EAGAIN (sem_trywait()) The operation could  not  be  performed  without
59              blocking (i.e., the semaphore currently has the value zero).
60
61       EINTR  The call was interrupted by a signal handler; see signal(7).
62
63       EINVAL sem is not a valid semaphore.
64
65       EINVAL (sem_timedwait()) The value of abs_timeout.tv_nsecs is less than
66              0, or greater than or equal to 1000 million.
67
68       ETIMEDOUT
69              (sem_timedwait()) The call timed out before the semaphore  could
70              be locked.
71

ATTRIBUTES

73       For  an  explanation  of  the  terms  used  in  this  section,  see at‐
74       tributes(7).
75
76       ┌────────────────────────────────────────────┬───────────────┬─────────┐
77Interface                                   Attribute     Value   
78       ├────────────────────────────────────────────┼───────────────┼─────────┤
79sem_wait(), sem_trywait(), sem_timedwait()  │ Thread safety │ MT-Safe │
80       └────────────────────────────────────────────┴───────────────┴─────────┘
81

STANDARDS

83       POSIX.1-2008.
84

HISTORY

86       POSIX.1-2001.
87

EXAMPLES

89       The (somewhat trivial) program  shown  below  operates  on  an  unnamed
90       semaphore.   The program expects two command-line arguments.  The first
91       argument specifies a seconds value that is used to set an  alarm  timer
92       to  generate  a SIGALRM signal.  This handler performs a sem_post(3) to
93       increment the semaphore  that  is  being  waited  on  in  main()  using
94       sem_timedwait().  The second command-line argument specifies the length
95       of the timeout, in seconds, for sem_timedwait().  The  following  shows
96       what happens on two different runs of the program:
97
98           $ ./a.out 2 3
99           About to call sem_timedwait()
100           sem_post() from handler
101           sem_timedwait() succeeded
102           $ ./a.out 2 1
103           About to call sem_timedwait()
104           sem_timedwait() timed out
105
106   Program source
107
108       #include <errno.h>
109       #include <semaphore.h>
110       #include <signal.h>
111       #include <stdio.h>
112       #include <stdlib.h>
113       #include <time.h>
114       #include <unistd.h>
115
116       #include <assert.h>
117
118       sem_t sem;
119
120       #define handle_error(msg) \
121           do { perror(msg); exit(EXIT_FAILURE); } while (0)
122
123       static void
124       handler(int sig)
125       {
126           write(STDOUT_FILENO, "sem_post() from handler\n", 24);
127           if (sem_post(&sem) == -1) {
128               write(STDERR_FILENO, "sem_post() failed\n", 18);
129               _exit(EXIT_FAILURE);
130           }
131       }
132
133       int
134       main(int argc, char *argv[])
135       {
136           struct sigaction sa;
137           struct timespec ts;
138           int s;
139
140           if (argc != 3) {
141               fprintf(stderr, "Usage: %s <alarm-secs> <wait-secs>\n",
142                       argv[0]);
143               exit(EXIT_FAILURE);
144           }
145
146           if (sem_init(&sem, 0, 0) == -1)
147               handle_error("sem_init");
148
149           /* Establish SIGALRM handler; set alarm timer using argv[1]. */
150
151           sa.sa_handler = handler;
152           sigemptyset(&sa.sa_mask);
153           sa.sa_flags = 0;
154           if (sigaction(SIGALRM, &sa, NULL) == -1)
155               handle_error("sigaction");
156
157           alarm(atoi(argv[1]));
158
159           /* Calculate relative interval as current time plus
160              number of seconds given argv[2]. */
161
162           if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
163               handle_error("clock_gettime");
164
165           ts.tv_sec += atoi(argv[2]);
166
167           printf("%s() about to call sem_timedwait()\n", __func__);
168           while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
169               continue;       /* Restart if interrupted by handler. */
170
171           /* Check what happened. */
172
173           if (s == -1) {
174               if (errno == ETIMEDOUT)
175                   printf("sem_timedwait() timed out\n");
176               else
177                   perror("sem_timedwait");
178           } else
179               printf("sem_timedwait() succeeded\n");
180
181           exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
182       }
183

SEE ALSO

185       clock_gettime(2),  sem_getvalue(3), sem_post(3), timespec(3), sem_over‐
186       view(7), time(7)
187
188
189
190Linux man-pages 6.05              2023-07-20                       sem_wait(3)
Impressum