Perl中的fork()函数

Perl提供了一个fork()函数,该函数对应于同名的Unix系统调用。在大多数类似Unix的平台上,fork()系统调用是可用的,Perl的fork()只是简单地调用它。在某些平台(如Windows)上,fork()系统调用不可用,可以构建Perl以在解释器级别模拟fork()。

fork()函数用于克隆当前进程。此调用将在同一点创建一个运行相同程序的新进程。它将子pid返回到父进程,将0返回到子进程,或者在fork不成功时返回。

可以在进程内使用exec()函数启动请求的可执行文件,该文件将在单独的进程区域中执行,exec()将等待它完成,然后以与该进程相同的退出状态退出。

示例

#!/usr/bin/perl
if(!defined($pid = fork())) {
   #fork返回了undef,所以没有成功
   die "Cannot fork a child: $!";
} elsif ($pid == 0) {
   print "Printed by child process\n";
   exec("date") || die "can't exec date: $!";
} else {
   #fork返回0或undef
   #所以这个分支是父级的
   print "Printed by parent process\n";
   $ret = waitpid($pid, 0);
   print "Completed process id: $ret\n";
}
1;

输出结果

执行上述代码后,将产生以下结果-

Printed by parent process
Printed by child process
Tue Sep 17 15:41:08 CDT 2013
Completed process id: 17777

可以将wait()waitpid()作为由返回的伪进程ID进行传递fork()。这些调用将正确地等待伪进程的终止并返回其状态。如果您使用waitpid()函数在没有等待孩子的情况下进行分叉,则会堆积僵尸。在Unix系统上,可以通过将$SIG {CHLD}设置为“ IGNORE”来避免这种情况,如下所示:

示例

#!/usr/bin/perl
local $SIG{CHLD} = "IGNORE";
if(!defined($pid = fork())) {
   #fork返回了undef,所以没有成功
   die "Cannot fork a child: $!";
} elsif ($pid == 0) {
   print "Printed by child process\n";
   exec("date") || die "can't exec date: $!";
} else {
   #fork返回0或undef
   #所以这个分支是父级的
   print "Printed by parent process\n";
   $ret = waitpid($pid, 0);
   print "Completed process id: $ret\n";
}
1;

输出结果

执行上述代码后,将产生以下结果-

Printed by parent process
Printed by child process
Tue Sep 17 15:44:07 CDT 2013
Completed process id: -1