#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,强制默认。 的。另一方面,当我运行这些注释行而不是运行所需信号时。这是什么原因?
答案 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脚本旨在守护进程,或者您打算在处理程序中使用exec
或die
。
如果您无法编辑正在调用的Perl脚本,那么我建议在STDERR
之前向execvp
打印一行,告诉用户忽略虚假警告。例如,
fputs("The next line is a harmless warning.\n", stderr);