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