如何在Perl中解雇并忘记进程?

时间:2010-01-25 16:49:15

标签: perl process fire-and-forget

有人可以告诉我如何在Perl中解雇并忘记一个进程吗?我已经看过ruby: how to fire and forget a subprocess?在Ruby中做同样的事情了。

4 个答案:

答案 0 :(得分:17)

perlfaq8回答How do I start a process in the background?


多个模块可以启动其他不阻止Perl的进程 程序。您可以使用IPC :: Open3,Parallel :: Jobs,IPC :: Run等等 POE模块。有关详细信息,请参阅CPAN。

您也可以使用

system("cmd &")

或者你可以使用perlfunc中“fork”中记录的fork,还有 perlipc中的例子。有些事情要注意,如果你在Unix上 - 喜欢系统:

共享STDIN,STDOUT和STDERR

主要过程和背景(“孩子”) process)共享相同的STDIN,STDOUT和STDERR文件句柄。如果 两者都试图立即访问它们,可能会发生奇怪的事情。您 可能想为孩子关闭或重新打开这些。你可以得到 通过“打开”管道(参见perlfunc中的“打开”),然后打开 一些系统这意味着子进程不能比这更长寿 父节点。

<强>信号

你必须抓住SIGCHLD信号,也可能是SIGPIPE。 在后台进程完成时发送SIGCHLD。 SIGPIPE是 写入子进程已关闭的文件句柄时发送 (未经编辑的SIGPIPE会导致程序无声地死亡)。 这不是“system(”cmd&amp;“)”的问题。

<强>僵尸

你必须准备好“收获”子进程 饰面。

   $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);

有关执行此操作的其他代码示例,请参阅perlipc中的“Signals”。 僵尸不是“system(”prog&amp;“)”的问题。

答案 1 :(得分:1)

如果你想要守护你的Perl脚本,我会调查Proc::Daemon.

答案 2 :(得分:0)

那么你不应该使用system(),因为我理解这个调用会在继续执行之前等待函数的返回。我会简单地向linux发出声明并以这种方式启动进程,但请记住这种方式将调用shell的新副本,因此如果你正在寻找性能,我不会在循环中执行此操作,例如:

process_name > /dev/null 2>&1 &;

这将开始将STDOUTSTDERR重定向到 / dev / null 的过程。

答案 3 :(得分:0)

如果您希望看门狗“子”进程在“父”进程退出时消失,那么您并不希望父进程“触发并忘记”子进程。您需要fork(如brian d foy所述)或将父级的PID传递给子级(因此后者可以轮询进程表 - 不推荐)。