【问题标题】:Nested signal handlers in CC中的嵌套信号处理程序
【发布时间】:2017-09-26 22:17:20
【问题描述】:

我想在两个独立进程的上下文中处理信号处理程序,即用于通知的写入器和读取器。写入器向读取器发送第一个信号 SIGUSR1,读取器循环直到它听到来自写入器的第二个信号 SIGUSR2。

reader.c

static volatile sig_atomic_t done_waiting; 

int handler1(int signal){
    done_waiting = 0;
     while( !done_waiting ){
            (void)fprintf(stdout, " reader waiting for sigusr2: done_waiting = %d\n", done_waiting );
    }
(void)fprintf(stdout, " reader received sigusr2 \n);
}

int handler2 (int signal){
         done_waiting = 1;
}

main(){
    signal(SIGUSR1, handler1);
    signal(SIGUSR2, handler2);
    sleep(5); // sleep till we start worker
}

在 writer.c 中,信号被发送给阅读器

main(){
    kill(pid_reader, SIGUSR1);
    sleep(5);
    kill (pid_reader, SIGUSR2);
}

当我先执行 reader 后执行 worker 时,程序在 while 循环中退出。并且作者打印出“未找到属于您的匹配进程”。

是否允许嵌套信号处理程序,如果允许,是否推荐?此外,作者是否有另一种替代机制来通知读者它已准备好?

【问题讨论】:

  • 请参阅How to avoid using printf() in signal handlers? 了解基本信息。您应该在信号处理程序中尽可能少做。您可以在信号处理程序中调用哪些函数有严格的限制——printf() 系列函数不在 OK 函数列表中(如果有任何帮助,strlen() 也不是——但有充分的理由printf() 等,我不知道strlen() 的充分理由。
  • 您不是“嵌套”信号处理程序,您已经为不同的信号安装了两个处理程序。此外,您应该查看sigsuspend(2) 和相关调用,它们允许等待信号(而不是您在while 循环中遇到的忙等待)。

标签: c signal-handling


【解决方案1】:

也许嵌套的 signals 实际上是你的意思,而不是嵌套的 signal handlers ?澄清一下,如果在 SIGUSR1 的处理程序正在执行时收到 SIGUSR2 会发生什么,这就是你的意思吗?我想是的,

我测试了您的代码,并进行了一些修改,以使读取器进程的 pid 进入写入器进程,我使用了 args 到 main。

我得到的结果是。

  1. 第一个读者很安静
  2. 收到 SIGUSR1 后,它开始连续写入等待 SIGUSR2
  3. 收到 SIGUSR2 时,会打印“reader received SIGUSR2”

这表明可以有嵌套信号。但是,我不会说它被推荐为有意的设计。 如 cmets 中所述,您应该尽可能少地在信号处理程序中执行操作,绝对不要在 while 循环中循环。 而且正如 cmets 中提到的,要非常小心你在信号上下文中调用的函数,printf() 是不行的,即使它看起来工作正常。

在 Linux 上测试,使用古老的内核 3.16 和 gcc 4.9

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2014-02-06
    • 2017-11-30
    • 1970-01-01
    • 2011-09-25
    • 2019-08-04
    相关资源
    最近更新 更多