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
13       int sem_trywait(sem_t *sem);
14
15       int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
16
17       Link with -lrt or -pthread.
18
19   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
20
21       sem_timedwait(): _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
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       EINTR  The call was interrupted by a signal handler; see signal(7).
63
64       EINVAL sem is not a valid semaphore.
65
66       The following additional error can occur for sem_trywait():
67
68       EAGAIN The operation could not be performed without blocking (i.e., the
69              semaphore currently has the value zero).
70
71       The following additional errors can occur for sem_timedwait():
72
73       EINVAL The  value  of  abs_timeout.tv_nsecs  is less than 0, or greater
74              than or equal to 1000 million.
75
76       ETIMEDOUT
77              The call timed out before the semaphore could be locked.
78

CONFORMING TO

80       POSIX.1-2001.
81

NOTES

83       A signal handler always interrupts a blocked call to one of these func‐
84       tions, regardless of the use of the sigaction(2) SA_RESTART flag.
85

EXAMPLE

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

SEE ALSO

183       clock_gettime(2),   sem_getvalue(3),   sem_post(3),    sem_overview(7),
184       time(7)
185

COLOPHON

187       This  page  is  part of release 3.25 of the Linux man-pages project.  A
188       description of the project, and information about reporting  bugs,  can
189       be found at http://www.kernel.org/doc/man-pages/.
190
191
192
193Linux                             2010-02-25                       SEM_WAIT(3)
Impressum