将"关闭"替换为"打开""/dev/null"?



我们有这样的Perl代码:

if (fork==0) {
# in child process close STDOUT и STDERR, for the parent process didn't wait a response from the child and finished quickly
close(STDOUT); 
if (!defined fileno(CGI::Carp::SAVEERR)) {close(STDERR)} # TODO learn to close redirected STDERR
else        { close(CGI::Carp::SAVEERR); } 
# ...
}

我们在Perl中描述了问题:STDOUT重新打开为FH仅用于输入 - 为了解决这个问题,我建议不要关闭STDOUT,而是将其重新打开为"/dev/null"。

我应该在上面的代码中用open/dev/null替换所有close调用吗? 还是只close(STDOUT)close(STDERR)

这个替换不会破坏"父进程没有等待孩子的响应并快速完成"吗?

似乎有几件事需要澄清。

父进程确实需要收获其子进程(waitwaitpidSIGCHLD(,如果这就是您所说的">等待子进程的响应"的意思。 但是,如果父母先退出,孩子就会被init重新养育,一切都很好。这不受孩子关闭(重新打开(其溪流的影响。

至于"关闭"流,它们应该重定向(重新打开(到/dev/null。 例如,请参阅perlipc中子级与父级的完全分离,了解如何关闭流以进行守护程序化,以及问题中链接的帖子中的答案。

最后,似乎STDERR被保存并重定向到CGI::Carp中的文件。您现在是否要关闭或恢复它取决于意图/设计。如果STDERR要转到的日志和流本身应该关闭,您应该首先关闭日志,模块应该恢复STDERR(请检查(,然后将流重定向到/dev/null

总的来说,也许

my $pid = fork // die "Can't fork: $!";  #/
if ($pid == 0) 
{
open STDOUT, '>', '/dev/null' or die "Can't write to /dev/null: $!";
if (defined(fileno(CGI::Carp::SAVEERR)) 
{
close $fh_log_to_which_STDERR_was_redirected  or die $!;
close CGI::Carp::SAVEERR                      or die $!;
}    
open STDERR, '>', '/dev/null' or die "Can't write to /dev/null: $!";
...
}

但是请检查您的CGI::Carp处理,因为问题中没有这方面的信息。

没有给出fork的上下文,但请考虑 IPC::Run3 或 IPC::Run 来启动和管理进程。

最新更新