]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man3/sem_wait.3
man*/: srcfix (Use .P instead of .PP or .LP)
[thirdparty/man-pages.git] / man3 / sem_wait.3
1 '\" t
2 .\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .TH sem_wait 3 (date) "Linux man-pages (unreleased)"
7 .SH NAME
8 sem_wait, sem_timedwait, sem_trywait \- lock a semaphore
9 .SH LIBRARY
10 POSIX threads library
11 .RI ( libpthread ", " \-lpthread )
12 .SH SYNOPSIS
13 .nf
14 .B #include <semaphore.h>
15 .P
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 );
20 .fi
21 .P
22 .RS -4
23 Feature Test Macro Requirements for glibc (see
24 .BR feature_test_macros (7)):
25 .RE
26 .P
27 .BR sem_timedwait ():
28 .nf
29 _POSIX_C_SOURCE >= 200112L
30 .fi
31 .SH DESCRIPTION
32 .BR sem_wait ()
33 decrements (locks) the semaphore pointed to by
34 .IR sem .
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.
41 .P
42 .BR sem_trywait ()
43 is the same as
44 .BR sem_wait (),
45 except that if the decrement cannot be immediately performed,
46 then call returns an error
47 .RI ( errno
48 set to
49 .BR EAGAIN )
50 instead of blocking.
51 .P
52 .BR sem_timedwait ()
53 is the same as
54 .BR sem_wait (),
55 except that
56 .I abs_timeout
57 specifies a limit on the amount of time that the call
58 should block if the decrement cannot be immediately performed.
59 The
60 .I abs_timeout
61 argument points to a
62 .BR timespec (3)
63 structure that specifies an absolute timeout
64 in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
65 .P
66 If the timeout has already expired by the time of the call,
67 and the semaphore could not be locked immediately,
68 then
69 .BR sem_timedwait ()
70 fails with a timeout error
71 .RI ( errno
72 set to
73 .BR ETIMEDOUT ).
74 .P
75 If the operation can be performed immediately, then
76 .BR sem_timedwait ()
77 never fails with a timeout error, regardless of the value of
78 .IR abs_timeout .
79 Furthermore, the validity of
80 .I abs_timeout
81 is not checked in this case.
82 .SH RETURN VALUE
83 All of these functions return 0 on success;
84 on error, the value of the semaphore is left unchanged,
85 \-1 is returned, and
86 .I errno
87 is set to indicate the error.
88 .SH ERRORS
89 .TP
90 .B EAGAIN
91 .RB ( sem_trywait ())
92 The operation could not be performed without blocking (i.e., the
93 semaphore currently has the value zero).
94 .TP
95 .B EINTR
96 The call was interrupted by a signal handler; see
97 .BR signal (7).
98 .TP
99 .B EINVAL
100 .I sem
101 is not a valid semaphore.
102 .TP
103 .B EINVAL
104 .RB ( sem_timedwait ())
105 The value of
106 .I abs_timeout.tv_nsecs
107 is less than 0, or greater than or equal to 1000 million.
108 .TP
109 .B ETIMEDOUT
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(?).
114 .SH ATTRIBUTES
115 For an explanation of the terms used in this section, see
116 .BR attributes (7).
117 .TS
118 allbox;
119 lbx lb lb
120 l l l.
121 Interface Attribute Value
122 T{
123 .na
124 .nh
125 .BR sem_wait (),
126 .BR sem_trywait (),
127 .BR sem_timedwait ()
128 T} Thread safety MT-Safe
129 .TE
130 .SH STANDARDS
131 POSIX.1-2008.
132 .SH HISTORY
133 POSIX.1-2001.
134 .SH EXAMPLES
135 The (somewhat trivial) program shown below operates on an
136 unnamed semaphore.
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
140 .B SIGALRM
141 signal.
142 This handler performs a
143 .BR sem_post (3)
144 to increment the semaphore that is being waited on in
145 .I main()
146 using
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:
152 .P
153 .in +4n
154 .EX
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
162 .EE
163 .in
164 .SS Program source
165 \&
166 .\" SRC BEGIN (sem_wait.c)
167 .EX
168 #include <errno.h>
169 #include <semaphore.h>
170 #include <signal.h>
171 #include <stdio.h>
172 #include <stdlib.h>
173 #include <time.h>
174 #include <unistd.h>
175 \&
176 #include <assert.h>
177 \&
178 sem_t sem;
179 \&
180 #define handle_error(msg) \e
181 do { perror(msg); exit(EXIT_FAILURE); } while (0)
182 \&
183 static void
184 handler(int sig)
185 {
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);
189 _exit(EXIT_FAILURE);
190 }
191 }
192 \&
193 int
194 main(int argc, char *argv[])
195 {
196 struct sigaction sa;
197 struct timespec ts;
198 int s;
199 \&
200 if (argc != 3) {
201 fprintf(stderr, "Usage: %s <alarm\-secs> <wait\-secs>\en",
202 argv[0]);
203 exit(EXIT_FAILURE);
204 }
205 \&
206 if (sem_init(&sem, 0, 0) == \-1)
207 handle_error("sem_init");
208 \&
209 /* Establish SIGALRM handler; set alarm timer using argv[1]. */
210 \&
211 sa.sa_handler = handler;
212 sigemptyset(&sa.sa_mask);
213 sa.sa_flags = 0;
214 if (sigaction(SIGALRM, &sa, NULL) == \-1)
215 handle_error("sigaction");
216 \&
217 alarm(atoi(argv[1]));
218 \&
219 /* Calculate relative interval as current time plus
220 number of seconds given argv[2]. */
221 \&
222 if (clock_gettime(CLOCK_REALTIME, &ts) == \-1)
223 handle_error("clock_gettime");
224 \&
225 ts.tv_sec += atoi(argv[2]);
226 \&
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. */
230 \&
231 /* Check what happened. */
232 \&
233 if (s == \-1) {
234 if (errno == ETIMEDOUT)
235 printf("sem_timedwait() timed out\en");
236 else
237 perror("sem_timedwait");
238 } else
239 printf("sem_timedwait() succeeded\en");
240 \&
241 exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
242 }
243 .EE
244 .\" SRC END
245 .SH SEE ALSO
246 .BR clock_gettime (2),
247 .BR sem_getvalue (3),
248 .BR sem_post (3),
249 .BR timespec (3),
250 .BR sem_overview (7),
251 .BR time (7)