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 -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_timedwait() succeeded
100           $ ./a.out 2 1
101           About to call sem_timedwait()
102           sem_timedwait() timed out
103
104   Program source
105
106       #include <unistd.h>
107       #include <stdio.h>
108       #include <stdlib.h>
109       #include <semaphore.h>
110       #include <time.h>
111       #include <assert.h>
112       #include <errno.h>
113       #include <signal.h>
114
115       sem_t sem;
116
117       #define handle_error(msg) \
118           do { perror(msg); exit(EXIT_FAILURE); } while (0)
119
120       static void
121       handler(int sig)
122       {
123           write(STDOUT_FILENO, "sem_post() from handler\n", 24);
124           if (sem_post(&sem) == -1) {
125               write(STDERR_FILENO, "sem_post() failed\n", 18);
126               _exit(EXIT_FAILURE);
127           }
128       }
129
130       int
131       main(int argc, char *argv[])
132       {
133           struct sigaction sa;
134           struct timespec ts;
135           int s;
136
137           if (argc != 3) {
138               fprintf(stderr, "Usage: %s <alarm-secs> <wait-secs>\n",
139                       argv[0]);
140               exit(EXIT_FAILURE);
141           }
142
143           if (sem_init(&sem, 0, 0) == -1)
144               handle_error("sem_init");
145
146           /* Establish SIGALRM handler; set alarm timer using argv[1] */
147
148           sa.sa_handler = handler;
149           sigemptyset(&sa.sa_mask);
150           sa.sa_flags = 0;
151           if (sigaction(SIGALRM, &sa, NULL) == -1)
152               handle_error("sigaction");
153
154           alarm(atoi(argv[1]));
155
156           /* Calculate relative interval as current time plus
157              number of seconds given argv[2] */
158
159           if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
160               handle_error("clock_gettime");
161
162           ts.tv_sec += atoi(argv[2]);
163
164           printf("main() about to call sem_timedwait()\n");
165           while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
166               continue;       /* Restart if interrupted by handler */
167
168           /* Check what happened */
169
170           if (s == -1) {
171               if (errno == ETIMEDOUT)
172                   printf("sem_timedwait() timed out\n");
173               else
174                   perror("sem_timedwait");
175           } else
176               printf("sem_timedwait() succeeded\n");
177
178           exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
179       }
180

SEE ALSO

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

COLOPHON

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