我是fork概念的新手。我正在尝试使用fork循环的简单脚本,期望执行两次但最终会发生3次。是因为我没有退出子进程吗?你能澄清一下吗
脚本:
#!/usr/bin/perl
open(my $fh, '>', 'report.txt');
print $fh "before invoke fork \n";
close $fh;
@list = (1, 2);
foreach $a (@list){
if($pid = fork){
open(my $fh, '>>', 'report.txt');
print $fh "Parent process! $a $pid\n";
close $fh;
}else {
open(my $fh, '>>', 'report.txt');
print $fh "Child process $a $pid\n";
close $fh;
}
}
输出:
在调用fork之前 我的第二份报告由perl 1 1808生成 我的第二份报告由perl 2 1809生成 我的thrid报告由perl 2 0生成 我的thrid报告由perl 1 0生成 我的第二份报告由perl 2 1810生成 我的thrid报告由perl 2 0生成
答案 0 :(得分:2)
这是因为fork()
这两个进程从开始的点完全相同。
所以'孩子1'将继续运行,并继续循环,并运行迭代2'。
所以父会分叉两次,子1会分叉一次,子2 - 因为它是最后一次循环迭代 - 根本不会分叉。
我建议你真的应该考虑Parallel::ForkManager
因为它简化了很多。还有 - 启用use strict;
和use warnings
。并且不使用单字母变量,尤其不是$a
。
这里有一些example code如何使用Parallel::ForkManager
。
然而,要解决您的问题 - 在子节中坚持last
将导致它摆脱循环。
答案 1 :(得分:1)
您没有在循环中等待子进程。关于fork in循环有一个很好的解释:
也有手册。
http://perldoc.perl.org/perlfork.html
尽量小心叉子中的所有可能性。对待问题很重要!一种简单,好的和推荐的实施方式:
use strict;
use warning;
use Carp qw/confess/;
my $pid = fork;
if(!defined($pid)){
confess "\nWhy you hates me, O.S.? Why?\nANSWER: $!\n\n";
}
elsif($pid == 0){
#Child process. Do something and exit
}
else{
#Parent process
waitpid $pid,0;
}
此示例中未描述其他相关功能。要详细了解相关信息,请查看上面链接的manual