当我在if
条件内派生一个新进程时,令人惊讶的是if
和else
块都被执行。
根据执行该方法时的perl fork
子例程文档,根据分叉是否失败,它分别返回undef
和PID
。
下面是两个块都被执行的代码。
if(my $a = fork ) {
say "if block";
} else {
say "else block";
}
输出:
如果块
否则阻止
就像我手动返回那些一样,根据我返回0还是1,仅执行一个块。
sub a { 1; }
if(my $a = a ) {
say "if block";
} else {
say "else block";
}
输出:
如果阻止
知道为什么会这样吗?
答案 0 :(得分:4)
根据执行该方法的perl
fork
子例程文档,根据分叉是否失败,它分别返回undef
和PID
。
不完全是。它实际上说如下:
它将子pid返回到父进程,将
0
返回到子进程,如果fork不成功,则返回undef。
所以
fork
返回子进程的PID,因此父进程输出if block
。fork
返回0
,因此子进程输出else block
。通过检查返回的值,您可以让父母和孩子做不同的事情。
答案 1 :(得分:2)
如果还通过每个$$
语句输出进程ID(say
特殊变量),则更容易看到正在发生的事情:
use v5.10;
if( fork ) {
say "$$ (parent): if block";
} else {
say "$$ (child): else block";
}
然后您将看到您从两个不同的进程获得了输出:
19997 (parent): if block
20024 (child): else block
通常,父进程继续执行其操作,而子进程继续执行您要卸载的所有工作。但是,子级继承父级的标准文件句柄,因此输出将移至同一位置。如果您不想这样做,则可以立即更改子级(或我的父级)中的标准输出(及其他):
use v5.10;
if( fork ) {
say "$$ (parent): if block";
} else {
say "$$ (child): else block";
open STDOUT, ...
}
如果您希望当前进程变成其他进程(以便您仍然只有一个进程),请查看exec。