sleep Function
We've used the sleep function in numerous examples
throughout the text, and we showed two flawed implementations of it below
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
Returns: 0 or number of unslept seconds
This function causes the calling process to be suspended
until either
- The amount of wall clock time specified by seconds has elapsed.
- A signal is caught by the process and the signal handler returns.
As with an alarm signal, the actual return may be at a
time later than requested, because of other system activity.
In case 1, the return value is 0. When sleep returns
early, because of some signal being caught (case 2), the return value is the
number of unslept seconds (the requested time minus the actual time slept).
Although sleep can be implemented with the alarm function,
this isn't required. If alarm is used, however, there can be interactions
between the two functions. The POSIX.1 standard leaves all these interactions
unspecified. For example, if we do an alarm(10) and 3 wall clock seconds later
do a sleep(5), what happens? The sleep will return in 5 seconds (assuming that
some other signal isn't caught in that time), but will another SIGALRM be
generated 2 seconds later? These details depend on the implementation.
Solaris 9 implements sleep using alarm. The Solaris sleep(3)
manual page says that a
previously scheduled alarm is properly handled. For
example, in the preceding scenario, before sleep returns, it will reschedule
the alarm to happen 2 seconds later; sleep returns 0 in this case. (Obviously, sleep
must save the address of the signal handler for SIGALRM and reset it before
returning.) Also, if we do an alarm(6) and 3 wall clock seconds later do a sleep(5),
the sleep returns in 3 seconds (when the alarm goes off), not in 5 seconds.
Here, the return value from sleep is 2 (the number of unslept seconds).
FreeBSD 5.2.1, Linux 2.4.22, and Mac OS X 10.3, on the
other hand, use another technique: the delay is provided by nanosleep(2). This
function is specified to be a high-resolution delay by the real-time extensions
in the Single UNIX Specification. This function allows the implementation of sleep
to be independent of signals.
For portability, you shouldn't make any assumptions about
the implementation of sleep, but if you have any intentions of mixing calls to sleep
with any other timing functions, you need to be aware of possible interactions.
Example:
Figure below shows an implementation of the POSIX.1 sleep
function. This function handles signals reliably, avoiding the race condition in
the earlier implementation. We still do not handle any interactions with
previously set alarms. (As we mentioned, these interactions are explicitly
undefined by POSIX.1.)
It takes more code to write this reliable implementation
than what is shown in Figure below. We don't use any form of nonlocal branching, so there is no effect on other signal
handlers that may be executing when the SIGALRM is handled.
No comments:
Post a Comment