简体   繁体   English

Linux system()和信号处理程序导致竞争状况?

[英]Linux system() and signal handler cause a race condition?

I came across a problem with code like: 我遇到了类似的代码问题:

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. In Linux(Cent OS) environment, sighandler() will be triggered after system() finishes. 在Linux(Cent OS)环境中, sighandler()将在system()完成后触发。 But on Mac OS X, sighandler() is not called in the same condition. 但是在Mac OS X上, sighandler()的调用条件不同。 Is this a known difference between Linux and BSD/UNIX systems? 这是Linux与BSD / UNIX系统之间的已知区别吗?

  2. The real problem is that in a GTK(C Language) program, SIGCHLD is bind with sighandler() in the main routine. 真正的问题是,在GTK(C语言)程序中, SIGCHLD在主例程中与sighandler()绑定。 But later I discover that a system() called in a callback function of child window GTK Button always returns -1. 但是后来我发现在子窗口GTK Button的回调函数中调用的system()始终返回-1。 I'm fully sure that SIGCHLD is not bind with SIG_IGN and it is still bind sighandler() . 我完全确定SIGCHLD不会与SIG_IGN绑定,并且仍与sighandler()绑定。 Is it possible that waitpid in sighandler() catch the dead child process before waitpid() in system() which is intended to handle the dead child process? sighandler()中的waitpid是否有可能在system()中用于处理死子进程的waitpid()之前捕获死子进程?

Here's what the POSIX specification of system says regarding SIGCHLD : 这是关于SIGCHLD系统 POSIX规范所说的:

The system() function shall ignore the SIGINT and SIGQUIT signals, and shall block the SIGCHLD signal, while waiting for the command to terminate. 在等待命令终止时,system()函数将忽略SIGINT和SIGQUIT信号,并阻塞SIGCHLD信号。

Blocking SIGCHLD while waiting for the child to terminate prevents the application from catching the signal and obtaining status from system()'s child process before system() can get the status itself. 在等待子进程终止时阻塞SIGCHLD可以防止应用程序在system()获取状态本身之前捕获信号并从system()的子进程中获取状态。

Note that if the application is catching SIGCHLD signals, it will receive such a signal before a successful system() call returns. 请注意,如果应用程序正在捕获SIGCHLD信号,它将在成功的system()调用返回之前接收到此类信号。

The last point is because when system() unblocks SIGCHLD , the pending signal is delivered, and it goes to the application's handler. 最后一点是因为当system()解除对SIGCHLD的阻止时,将传递挂起的信号,并将其传递给应用程序的处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM