如何在不同的脚本中使用Perl进行fork?

pab*_*rti 1 perl fork system process

我在Perl中有一个使用system 命令创建另一个进程的进程,我将它留在内存中并传递一些这样的变量:


my $var1 = "Hello";
my $var1 = "World";
system "./another_process.pl $var1 $var2 &";

但系统命令只返回结果,我需要获取PID.我想做一些像fork的东西.我该怎么办?我怎么能用不同的脚本制作像fork这样的东西?

提前致谢!

Zai*_*aid 5

Perl有一个fork功能.

请参阅perldoc perlfaq8- 如何在后台启动流程?


(由brian d foy提供)

没有一种方法可以在后台运行代码,因此在程序转移到其他任务之前,您无需等待它完成.流程管理取决于您的特定操作系统,许多技术都在perlipc中.一些CPAN模块也许能够提供帮助,包括 IPC::Open2IPC::Open3 , IPC::Run , Parallel::Jobs , Parallel::ForkManager , POE , Proc::Background ,和 Win32::Process .

您可能使用许多其他模块,因此请检查这些命名空间以获取其他选项.如果您使用的是类Unix系统,那么您可以在系统调用中放弃,并在命令末尾添加&:

    system("cmd &")
Run Code Online (Sandbox Code Playgroud)

您也可以尝试使用 fork,如 perlfunc (尽管这与许多模块将为您做的事情相同).

STDIN,STDOUT和STDERR是共享的

主进程和后台进程("子进程")共​​享相同的STDIN,STDOUT和STDERR文件句柄.如果两者都试图立即访问它们,可能会发生奇怪的事情.您可能想要为孩子关闭或重新打开这些.您可以通过打开管道来解决这个问题(请参阅打开),但在某些系统上,这意味着子进程不能超过父进程.

信号

你必须捕获SIGCHLD信号,也可能是SIGPIPE.在后台进程完成时发送SIGCHLD.当您写入子进程已关闭的文件句柄时,会发送SIGPIPE(未处理的SIGPIPE会导致程序无声地死亡).这不是问题system("cmd&").

植物大战僵尸

你必须准备在完成后"收获"子进程.$ SIG {CHLD} = sub {wait}; $ SIG {CHLD} ='IGNORE'; 你也可以使用双叉.你马上等待()为你的第一个孩子,一旦它退出,init守护进程将等待你的孙子.

unless ($pid = fork) {
        unless (fork) { 
            exec "what you really wanna do";
            die "exec failed!";
  }

        exit 0;
    }

    waitpid($pid, 0);
Run Code Online (Sandbox Code Playgroud)

有关perlipc 执行此操作的其他代码示例,请参阅信号 .僵尸不是问题 system("prog &").system("prog &").