Linux系统()和信号处理程序导致竞争条件?

时间:2014-07-31 14:25:41

标签: c linux unix gtk signals

我遇到了类似代码的问题:

void sighandler(int signo)
{
    printf("sighandler() called\n");

    pid_t pid;
    pid = waitpid(-1, NULL, WNOHANG);
    if(pid >= 0)
    {
        printf("Caught by sighandler(): pid = %d\n", pid);
    }
    else
    {
        perror("sighandler pid failed");
    }
}


int main(void)
{
    int ret = 0;
    pid_t pid;

    signal(SIGCHLD, sighandler);

    ret = system("ls -al");

    if(ret < 0)
    {
        perror("system failed");
        printf("return value is %d\n", ret);
    }

    return 0;
}
  1. 在Linux(Cent OS)环境中,sighandler()完成后将触发system()。但是在Mac OS X上,sighandler()未在相同条件下调用。这是Linux和BSD / UNIX系统之间的已知区别吗?

  2. 真正的问题是在GTK(C语言)程序中,SIGCHLD在主例程中与sighandler()绑定。但后来我发现在子窗口GTK Button的回调函数中调用的system()总是返回-1。我完全确定SIGCHLD不与SIG_IGN绑定,它仍然绑定sighandler() waitpid中的sighandler()是否有可能在waitpid() system()之前捕获死亡子进程,以便处理死子进程? < / p>

1 个答案:

答案 0 :(得分:0)

以下是关于SIGCHLD的{​​{3}}的POSIX规范:

  

system()函数应忽略SIGINT和SIGQUIT信号,并在等待命令终止时阻止SIGCHLD信号。

     

在等待子进程终止时阻塞SIGCHLD会阻止应用程序捕获信号并从system()的子进程获取状态,然后system()才能获得状态。

     

请注意,如果应用程序正在捕获SIGCHLD信号,它将在成功的system()调用返回之前收到此类信号。

最后一点是因为当system()取消阻止SIGCHLD时,挂起的信号会被传递,然后它会转到应用程序的处理程序。