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