【问题标题】:signal handling by sigaction通过 sigaction 处理信号
【发布时间】:2012-06-21 15:14:15
【问题描述】:

当我遇到此代码和 cmets 时,我正在阅读有关 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 为程序的其余部分设置的处理程序处理(我知道,这听起来很荒谬)

请解释!!

【问题讨论】:

  • 代码是否分叉任何进程或设置管道?这个 sn-p 中是否缺少任何相关代码?这是我能看到的唯一创建竞争条件的条件。
  • @squiguy...我认为这无关紧要...我从here得到这个

标签: unix event-handling signals signal-handling


【解决方案1】:

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

【讨论】:

  • @twalberg...我现在明白了...只有一个问题...如果在 select() 阻塞时出现信号,则已知 select() 返回...但在它之后return 是我们设置的处理程序自动处理的信号,或者我们必须显式调用处理程序...
  • 我的理解是,如果信号发生在select()处于休眠状态时,处理程序会被调用,然后当处理程序返回时,系统会确定我们在信号之前处于select(),并安排select() 返回并指示它已被中断。所以select() 直到信号被处理后才会返回。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多