1SEM_WAIT(3)                Linux Programmer's Manual               SEM_WAIT(3)
2
3
4

NAME

6       sem_wait, sem_timedwait, sem_trywait - lock a semaphore
7

SYNOPSIS

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

DESCRIPTION

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

RETURN VALUE

57       All of these functions return 0 on success; on error, the value of  the
58       semaphore  is left unchanged, -1 is returned, and errno is set to indi‐
59       cate the error.
60

ERRORS

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

ATTRIBUTES

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

CONFORMING TO

87       POSIX.1-2001, POSIX.1-2008.
88

EXAMPLES

90       The (somewhat trivial) program shown below operates on an unnamed sema‐
91       phore.   The program expects two command-line arguments.  The first ar‐
92       gument specifies a seconds value that is used to set an alarm timer  to
93       generate  a SIGALRM signal.  This handler performs a sem_post(3) to in‐
94       crement  the  semaphore  that  is  being  waited  on  in  main()  using
95       sem_timedwait().  The second command-line argument specifies the length
96       of the timeout, in seconds, for sem_timedwait().  The  following  shows
97       what happens on two different runs of the program:
98
99           $ ./a.out 2 3
100           About to call sem_timedwait()
101           sem_post() from handler
102           sem_timedwait() succeeded
103           $ ./a.out 2 1
104           About to call sem_timedwait()
105           sem_timedwait() timed out
106
107   Program source
108
109       #include <unistd.h>
110       #include <stdio.h>
111       #include <stdlib.h>
112       #include <semaphore.h>
113       #include <time.h>
114       #include <assert.h>
115       #include <errno.h>
116       #include <signal.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("main() about to call sem_timedwait()\n");
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),   sem_overview(7),
186       time(7)
187

COLOPHON

189       This page is part of release 5.13 of the Linux  man-pages  project.   A
190       description  of  the project, information about reporting bugs, and the
191       latest    version    of    this    page,    can     be     found     at
192       https://www.kernel.org/doc/man-pages/.
193
194
195
196Linux                             2021-08-27                       SEM_WAIT(3)
Impressum