分类:
2008-12-08 12:18:00
10.19 sleep function
#include unsigned int sleep(unsigned int seconds); |
Returns: 0 or number of unslept seconds |
在linux
如下是一个使用alarm和suspend函数来实现的一个较alarm和pause函数安全的sleep的实现:
#include "apue.h"
static void
sig_alrm(int signo)
{
/* nothing to do, just returning
wakes up sigsuspend() */
}
unsigned int
sleep(unsigned int nsecs)
{
struct sigaction newact, oldact;
sigset_t newmask, oldmask, suspmask;
unsigned int unslept;
/* set our handler, save
previous information */
newact.sa_handler = sig_alrm;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(SIGALRM, &newact,
&oldact);
/* block SIGALRM and save
current signal mask */
sigemptyset(&newmask);
sigaddset(&newmask,
SIGALRM);
sigprocmask(SIG_BLOCK,
&newmask, &oldmask);
alarm(nsecs);
suspmask = oldmask;
sigdelset(&suspmask,
SIGALRM); /* make sure SIGALRM isn't
blocked */
sigsuspend(&suspmask); /* wait for any signal to be caught
*/
/* some signal has been
caught, SIGALRM is now blocked */
unslept = alarm(0);
sigaction(SIGALRM, &oldact,
NULL); /* reset previous action */
/* reset signal mask, which
unblocks SIGALRM */
sigprocmask(SIG_SETMASK,
&oldmask, NULL);
return(unslept);
}
这个实现依然存在一个缺点,它影响了外界的已经存在的alarm。但是它可以取消以前在调用alarm之后,调用pause()之前这段时间如果进程被schedule出去之后,收到了alarm信号的race condition情况,这种情况会造成进程丢失了alarm信号。而使用了alarm和suspend组和,在调用alarm之前,我们将alarm信号block,然后调用suspend,在suspend里面,将alarm信号unblock,当alarm, 所以不会丢失alarm信号,而suspend已被打断,返回到sleep函数里面,alarm又自动的被block。
最后,在sleep函数结束前,将alarm 信号的 handler以及signal 的mask都恢复到系统的默认值。