【问题标题】:Can't ignore signal CHLD, forcing to default不能忽略信号 CHLD,强制默认
【发布时间】:2017-08-18 17:07:21
【问题描述】:
 #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 脚本,并且我希望父进程在不等待其子进程的情况下完成。因此,我在开始时使用了 signal(SIGCHLD,SIG_IGN) 来忽略完成时的子信号并避免僵尸。但是当我运行代码时,它给我的错误是 Can't ignore signal CHLD,强制默认。 。另一方面,当我运行那些注释行而不是运行所需的信号时。这是什么原因?

【问题讨论】:

    标签: sigchld


    【解决方案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 脚本,那么我建议在 execvp 之前打印一行到 STDERR,告诉用户忽略虚假警告。例如,

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      • 2014-08-20
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多