perl在if语句中执行两个块的过程

时间:2019-07-11 09:10:34

标签: perl fork

当我在if条件内派生一个新进程时,令人惊讶的是ifelse块都被执行。
根据执行该方法时的perl fork子例程文档,根据分叉是否失败,它分别返回undefPID

下面是两个块都被执行的代码。

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";
}
  

输出:
  如果阻止

知道为什么会这样吗?

2 个答案:

答案 0 :(得分:4)

  

根据执行该方法的perl fork子例程文档,根据分叉是否失败,它分别返回undefPID

不完全是。它实际上说如下:

  

它将子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