不能忽略信号CHLD,强制默认

时间:2017-08-18 17:07:22

标签: sigchld

 #include <sys/types.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <sys/wait.h>
 #include <signal.h>
 #include <iostream>
 #include <unistd.h>
 int main(){


        signal(SIGCHLD,SIG_IGN );
        pid_t pid  = vfork();
        if(pid <0){
            std::cout<< "Error: Fork failed at main!!!";
            exit(1);
        }else if (0 == pid){


            char * cmd[] ={(char*)"../work/C++11/Prj_LargeFile/script/Logger.pl",NULL};
            //char * cmd[] = {(char*)"pwd",NULL};
            //char * cmd[] = {(char*)"/usr/bin/perl",(char*)"../work/C++11/Prj_LargeFile/script/Logger.pl",NULL};

            execvp(cmd[0],cmd);


             _exit(0);
        }
}

我希望有孤儿子进程,它将在背景中运行perl脚本,我希望父进程在不等待其子进程的情况下完成。因此我在开始时使用信号(SIGCHLD,SIG_IGN)在完成时忽略子信号并避免僵尸。但是,当我运行代码时,它给出了我的错误不能忽略信号CHLD,强制默认。 的。另一方面,当我运行这些注释行而不是运行所需信号时。这是什么原因?

1 个答案:

答案 0 :(得分:1)

Perl发出此警告。就Perl而言,看起来最近版本的glibc(或Linux内核中可能的特定选项)已经取消了忽略SIGCHLD的能力。我不知道为什么会这样,但我刚刚在一个以前很高兴忽略SIGCHLD的系统上遇到过它。

根据perldoc perlipc,您应该查看更多信息,最好的办法是:

use POSIX ":sys_wait_h"; # for nonblocking read
$SIG{CHLD} = sub {
    while ((my $child = waitpid(-1, WNOHANG)) > 0) {
        # $Kid_Status{$child} = $?;
    }
};
# do something that forks...

$Kid_Status的行来自原始的perldoc,但我对其进行了评论,因为其意图是忽略子进程,我想明确while的内部没有'需要包含任何代码。有多种方法可以解决perldoc中处理子进程的问题,例如,如果您的Perl脚本旨在守护进程,或者您打算在处理程序中使用execdie

如果您无法编辑正在调用的Perl脚本,那么我建议在STDERR之前向execvp打印一行,告诉用户忽略虚假警告。例如,

fputs("The next line is a harmless warning.\n", stderr);