通过sigaction处理信号

时间:2012-06-21 15:14:15

标签: unix event-handling signals signal-handling

当我遇到这段代码和评论时,我正在阅读有关使用pselect系统调用的信息......

static void handler(int sig) { /* do nothing */  }

int main(int argc, char *argv[])
{
    fd_set readfds;
    struct sigaction sa;
    int nfds, ready;

    sa.sa_handler = handler;     /* Establish signal handler */
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGINT, &sa, NULL);
/* ... */    
    ready = select(nfds, &readfds, NULL, NULL, NULL);
/* ... */
}

this solution suffers from a race condition: if the SIGINT signal is delivered after
the call to sigaction(), but before the call to select(), it will fail to interrupt 
that select() call and will thus be lost.

现在我不确定 sigaction系统调用 ...最初我认为它有点保存一个与信号相对应的处理程序,就是这样......当信号到达它寻找其处理程序和处理程序执行...但如果这是正确的,那么对应于该信号的处理程序将被保存用于整个程序,并且它将在信号到达时执行...所以然而在sigaction和select之间的持续时间很短,信号将被处理 ......

但是此代码使得看起来信号仅在与sigaction的调用/执行一致时处理 ......在调用完成后信号将不会由sigaction设置的处理程序处理程序的其余部分(我知道,听起来很荒谬)

请解释!!

1 个答案:

答案 0 :(得分:2)

您需要在文章的上下文中查看该代码 - 代码正在尝试安排信号中断select()。提到的竞争条件不会导致sigaction()或信号处理程序以任何方式失败 - 它只是注意到信号可能在sigaction()调用和{{1}之间传递调用,这使得该模式对于实现期望的结果是不可接受的。无论是在select()之前,期间还是之后,您都可以在sigaction()之后的任何时间到达信号。但是,这不能用于可靠地为signal()提供早期中断路径,这就是本文的背景。