从 Perl 在后台运行作业,无需等待返回 [英] Running job in the background from Perl WITHOUT waiting for return

查看:46
本文介绍了从 Perl 在后台运行作业,无需等待返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我知道这个问题(或紧密变体)已经被问过一千次了.我真的花了几个小时在明显和不那么明显的地方寻找,但我可能遗漏了一些小东西.

First of all, I know this question (or close variations) have been asked a thousand times. I really spent a few hours looking in the obvious and the not-so-obvious places, but there may be something small I'm missing.

让我更清楚地定义问题:我正在编写一个时事通讯应用程序,其中我希望实际的发送过程是异步的.例如,用户点击发送",请求立即返回,然后他们可以检查特定页面的进度(例如,通过 AJAX).它是用传统的 LAMP 堆栈编写的.

Let me define the problem more clearly: I'm writing a newsletter app in which I want the actual sending process to be async. As in, user clicks "send", request returns immediately and then they can check the progress in a specific page (via AJAX, for example). It's written in your traditional LAMP stack.

在我使用的特定主机中,出于安全原因,PHP 的 exec() 和 system() 被禁用,但 Perl 的系统函数(exec、system 和反引号)不是.所以我的 workaround 解决方案是在 Perl 中创建一个触发"脚本,通过 PHP CLI 调用实际的发送者,并重定向到进度页面.

In the particular host I'm using, PHP's exec() and system() are disabled for security reasons, but Perl's system functions (exec, system and backticks) aren't. So my workaround solution was to create a "trigger" script in Perl that calls the actual sender via the PHP CLI, and redirects to the progress page.

到目前为止,发件人的电话所在的行:

The very line the calls the sender is, as of now:

system("php -q sender.php &");

问题是,它不会立即返回,而是等待脚本完成.我希望它在后台运行并让系统调用本身立即返回.我也尝试在我的 Linux 终端中运行一个类似的脚本,实际上直到脚本完成后才会显示提示,即使我的测试输出没有运行,表明它确实在后台运行.

Problem being, it's not returning immediately, but waiting for the script to finish. I want it to run in the background and have the system call itself return right away. I also tried running a similar script in my Linux terminal, and in fact the prompt doesn't show until after the script has finished, even though my test output doesn't run, indicating it's really running in the background.

  • Perl 的 exec() 函数 - 与 system() 的结果相同.
  • 将命令更改为:php -q sender.php | at now"),希望at"守护进程能够返回并且 PHP 进程本身不会附加到 Perl.
  • 间接"执行命令:/bin/sh -c 'php -q sender.php &'" - 仍然等待 sender.php 完成发送.
  • fork() 处理进程并在子进程中执行系统调用(希望分离进程) - 结果与上述相同

为了确保我没有遗漏任何明显的东西,我创建了一个 sleeper.php 脚本,它在退出前只休眠 5 秒.还有一个像这样的 test.cgi 脚本,逐字逐句:

Just to be sure that I'm not missing anything obvious, I created a sleeper.php script which just sleeps five seconds before exiting. And a test.cgi script that is like this, verbatim:

#!/usr/local/bin/perl
system("php sleeper.php &");
print "Content-type: text/html

done";

我现在应该尝试什么?

推荐答案

本质上,您需要守护"一个进程——fork 一个子进程,然后将它与父进程完全断开,这样父进程就可以安全地终止而不影响孩子.

Essentially you need to 'daemonize' a process -- fork off a child, and then entirely disconnect it from the parent so that the parent can safely terminate without affecting the child.

您可以使用 CPAN 模块轻松完成此操作Proc::Daemon:

You can do this easily with the CPAN module Proc::Daemon:

use Proc::Daemon;
# do everything you need to do before forking the child...

# make into daemon; closes all open fds
Proc::Daemon::Init();

这篇关于从 Perl 在后台运行作业,无需等待返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆