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