如何在 Perl 中触发并忘记进程?

发布于 2024-08-19 11:04:32 字数 171 浏览 5 评论 0原文

有人可以告诉我如何在 Perl 中“即发即忘”进程吗?我已经看过 ruby:如何触发并忘记子进程? 在 Ruby 中做同样的事情。

Can somebody please tell me how to fire-and-forget a process in Perl? I've already looked at ruby: how to fire and forget a subprocess? for doing the same in Ruby.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

五里雾 2024-08-26 11:04:32

来自 perlfaq8 的回答 如何在后台启动进程?


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

您还可以使用

system("cmd &")

或者可以使用 perlfunc 中“fork”中记录的 fork,并进一步
perlipc 中的示例。如果您使用的是 Unix,需要注意一些事情 -
像系统一样:

STDIN、STDOUT 和 STDERR 是共享的

主进程和后台进程(“子进程”)
进程)共享相同的 STDIN、STDOUT 和 STDERR 文件句柄。如果
两者都尝试同时访问它们,可能会发生奇怪的事情。你
可能想为孩子关闭或重新打开这些。你可以获得
围绕这个问题,“打开”一个管道(参见 perlfunc 中的“打开”),但是
在某些系统中,这意味着子进程不能比
父母。

信号

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

僵尸

你必须准备好“收割”子进程。
完成。

   $SIG{CHLD} = sub { wait };

   $SIG{CHLD} = 'IGNORE';

您也可以使用双叉。你立即 wait() 等待你的
第一个孩子,init 守护进程将 wait() 等待你的孙子
一旦它退出。

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

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

From perlfaq8's answer to How do I start a process in the background?


Several modules can start other processes that do not block your Perl
program. You can use IPC::Open3, Parallel::Jobs, IPC::Run, and some of
the POE modules. See CPAN for more details.

You could also use

system("cmd &")

or you could use fork as documented in "fork" in perlfunc, with further
examples in perlipc. Some things to be aware of, if you're on a Unix-
like system:

STDIN, STDOUT, and STDERR are shared

Both the main process and the backgrounded one (the "child"
process) share the same STDIN, STDOUT and STDERR filehandles. If
both try to access them at once, strange things can happen. You
may want to close or reopen these for the child. You can get
around this with "open"ing a pipe (see "open" in perlfunc) but on
some systems this means that the child process cannot outlive the
parent.

Signals

You'll have to catch the SIGCHLD signal, and possibly SIGPIPE too.
SIGCHLD is sent when the backgrounded process finishes. SIGPIPE is
sent when you write to a filehandle whose child process has closed
(an untrapped SIGPIPE can cause your program to silently die).
This is not an issue with "system("cmd&")".

Zombies

You have to be prepared to "reap" the child process when it
finishes.

   $SIG{CHLD} = sub { wait };

   $SIG{CHLD} = 'IGNORE';

You can also use a double fork. You immediately wait() for your
first child, and the init daemon will wait() for your grandchild
once it exits.

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

See "Signals" in perlipc for other examples of code to do this.
Zombies are not an issue with "system("prog &")".

攒眉千度 2024-08-26 11:04:32

如果你想守护你的 Perl 脚本,我会研究 Proc: :守护进程。

If you want to daemonize your Perl script I'd looking into Proc::Daemon.

彡翼 2024-08-26 11:04:32

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

:进程名称> /dev/null 2>&1 &;

这将启动将 STDOUTSTDERR 重定向到 /dev/null 的过程。

Well you shouldn't use system() as I understand this call will wait for the return of the function before continuing execution. I would simply shell out to linux and start the process that way, though keep in mind this way will envoke a new copy of the shell and so if you're looking for performance I wouldnt do this in a loop for example:

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

That will start the process redirecting STDOUT and STDERR to /dev/null.

知你几分 2024-08-26 11:04:32

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

If you want the watchdog "child" process to go away when the "parent" process exits then you don't really want the parent process to "fire and forget" the child process. You either need to fork (as described by brian d foy) or pass the PID of the parent to the child (so the latter can poll the process table - not recommended).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文