use LWP::Simple;
use Parallel::ForkManager;
@links=(
["http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-windows.exe","SweetHome3D-2.1-windows.exe"],
["http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-macosx.dmg","SweetHome3D-2.1-macosx.dmg"],
["http://prdownloads.sourceforge.net/sweethome3d/SweetHome3DViewer-2.1.zip","SweetHome3DViewer-2.1.zip"],
);
# Max 30 processes for parallel download
my $pm = new Parallel::ForkManager(30);
foreach my $linkarray (@links) {
my $pid = $pm->start and next; # do the fork
my ($link,$fn) = @$linkarray;
warn "Cannot get $fn from $link"
if getstore($link,$fn) != RC_OK;
print "$pid = $link is done ";
$pm->finish; # do the exit in the child process
}
$pm->wait_all_children;
执行此操作后,我的pid为零
0 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3DViewer-2.1.zip is done 0 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-macosx.dmg is done 0 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-windows.exe is done
但现在我真的在想它是否真的在做分叉。为什么我在Parallel :: ForkManager中将所有时间都设为0作为pid?
编辑2
我有2次更改
my $pid = $pm->start ; # do the fork
流程ID的和$$
21892 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-windows.exe is done 21893 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-windows.exe is done 21892 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-macosx.dmg is done 23120 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3D-2.1-macosx.dmg is done 21892 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3DViewer-2.1.zip is done 23146 = http://prdownloads.sourceforge.net/sweethome3d/SweetHome3DViewer-2.1.zip is done
但现在我得到两次。为什么我得到这个?
答案 0 :(得分:5)
不确定Parallel :: ForkManager实现,但如果它与标准fork()类似,则返回0,因为您处于子进程中。 Fork只会向父进程返回一个非零pid。
我忘了添加,在启动调用后给出'和next',代码的行为完全符合预期。
编辑2的注释:
由于您从启动调用中删除了'和next',因此父进程也在运行下载。我猜21892是父进程的pid,它将多次遍历循环
答案 1 :(得分:5)
关于Edit2下面的代码:
你改变了
my $pid = $pm->start and next;
到
my $pid = $pm->start ; # do the fork
现在你没有正确地做叉子。虽然之前只有孩子继续执行循环体,而父亲继续执行 next ,但现在两者都继续执行循环体。因此,您会看到父级的pid(21892)多次执行循环。
答案 2 :(得分:4)
看到那条线?
my $pid = $pm->start and next; # do the fork
父母获得pid,孩子只会看到0.如果你想从子进程中获取你的pid,只需使用魔术变量$$
。
更新:
对该行的引用并不意味着更改该行的邀请。但是看一下,很明显$ pid在行后面的代码中会为0,所以print $pid
打印0
而不是其他任何内容都不足为奇。
答案 3 :(得分:0)
forloop{
if (my $pid = $pm->start($linkarray)){
print "pid-i-got-from-child=$pid and this code is running under pid=$$\n";
next;
}
... and then continue with code processing in child process...
}
这将为您提供子pid,并继续使用fork处理代码。