linux 使用信号处理器实现睡眠功能

envsm3lx  于 5个月前  发布在  Linux
关注(0)|答案(1)|浏览(72)

在APUE的第10.19节(sleep,nanosleep,...)中,我们有一个sleep函数的实现。关于第11行,存在以下代码

/* block SIGALRM and save current signal mask */
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);

字符串
我的问题是:如果我们不阻止SIGALRM,会发生什么?
代码如下:

sleep(unsigned int seconds)
{
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(seconds);
suspmask = oldmask;

/* make sure SIGALRM isn’t blocked */
sigdelset(&suspmask, SIGALRM);

/* wait for any signal to be caught */
sigsuspend(&suspmask);

/* some signal has been caught, SIGALRM is now blocked */
unslept = alarm(0);

/* reset previous action */
sigaction(SIGALRM, &oldact, NULL);

/* reset signal mask, which unblocks SIGALRM */
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return(unslept);
}

edqdpe6u

edqdpe6u1#

目标是让SIGALRM信号处理程序中断阻塞的sigsuspend调用。如果处理程序没有被阻塞,信号可能会在sigsuspend调用进入之前到达,在这种情况下,代码(从处理程序返回后)将继续运行sigsuspend,在那里它将陷入死锁,等待已经到达的信号。
sigsuspend中,标准做法是先阻塞信号,然后再自动解除阻塞,这样做正是为了防止这类竞态条件。

相关问题