PHP 通过管道进入后台进程

发布于 2024-12-07 09:17:01 字数 299 浏览 0 评论 0原文

我正在尝试使用 popen 在后台运行 php 脚本。但是,我需要传递一个(相当大的)序列化对象。

$cmd = "php background_test.php >log/output.log &";
$fh = popen($cmd, 'w');
fwrite($fh, $data); 
fclose($fh);
//pclose($fh);

如果没有&符号,此代码可以正常执行,但父脚本将等待子脚本完成运行。使用 & 符号 STDIN 不会获取任何数据。

有什么想法吗?

I'm trying to use popen to run a php script in the background. However, I need to pass a (fairly large) serialized object.

$cmd = "php background_test.php >log/output.log &";
$fh = popen($cmd, 'w');
fwrite($fh, $data); 
fclose($fh);
//pclose($fh);

Without the ampersand this code executes fine but the parent script will wait until the child is finished running. With the ampersand STDIN gets no data.

Any ideas?

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

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

发布评论

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

评论(3

本宫微胖 2024-12-14 09:17:01

您可以尝试分叉,让子进程写入数据,主脚本继续正常运行。

类似这样的内容

// Fork a child process
$pid = pcntl_fork();

// Unable to fork
if ($pid == -1) {
    die('error');
}

// We are the parent
elseif ($pid) {

   // do nothing 
}

// We are the child
else {

    $cmd = "php background_test.php >log/output.log";
    $fh = popen($cmd, 'w');
    fwrite($fh, $data); 
    fclose($fh);
    exit();
}


// parent will continue here
// child will exit above

请在此处阅读更多相关信息:https://sites.google。 com/a/van-steenbeek.net/archive/php_pcntl_fork

另请检查 php 文档中的函数 pcntl_waitpid() (僵尸消失)。

You can try forking letting child process to write data and main script continue as normal.

Something like this

// Fork a child process
$pid = pcntl_fork();

// Unable to fork
if ($pid == -1) {
    die('error');
}

// We are the parent
elseif ($pid) {

   // do nothing 
}

// We are the child
else {

    $cmd = "php background_test.php >log/output.log";
    $fh = popen($cmd, 'w');
    fwrite($fh, $data); 
    fclose($fh);
    exit();
}


// parent will continue here
// child will exit above

Read more about it here: https://sites.google.com/a/van-steenbeek.net/archive/php_pcntl_fork

Also check function pcntl_waitpid() (zombies be gone) in php documentation.

冬天旳寂寞 2024-12-14 09:17:01

据我所知,php 中没有办法在后台发送进程并继续提供其 STDIN(但也许我错了)。您还有另外两个选择:

  1. 重构您的 background_test.php 以从命令行获取其输入,并在 php background_test.php arg1 arg2 ... >log/output 中转换您的命令行。 log &
  2. 如果您的输入相当长,请将其写入临时文件,然后将该文件输入到 background_test.php 脚本中,如以下

第 2 点的代码示例所示:

<?
$tmp_file = tempnam();
file_put_content($tmp_file, $data);
$cmd = "php background_test.php < $tmp_name > log/output.log &";
exec($cmd);

As far as I know there is no way in php to send a process in background and continue to feed its STDIN (but maybe I'm wrong). You have two other choices here:

  1. Refactor your background_test.php to get its input from command line and transform your command line in php background_test.php arg1 arg2 ... >log/output.log &
  2. If your input is pretty long, write it to a temporary file and then feed the background_test.php script with that file as in the following code

Example for point 2:

<?
$tmp_file = tempnam();
file_put_content($tmp_file, $data);
$cmd = "php background_test.php < $tmp_name > log/output.log &";
exec($cmd);
紫﹏色ふ单纯 2024-12-14 09:17:01

让后台进程监听套接字文件。然后从 PHP 打开套接字文件并将序列化数据发送到那里。当您的后台守护程序通过套接字接收连接时,使其分叉,读取数据然后进行处理。

你需要做一些阅读,但我认为这是实现这一目标的最佳方法。我所说的套接字是指 unix 套接字文件,但您也可以通过网络使用它。

http://gearman.org/ 也是 @Joshua 提到的一个不错的选择

Make a background processes listen to a socket file. Then open socket file from PHP and send your serialized data there. When your background daemon receives connection through the socket, make it fork, read data then process.

You would need to do some reading, but I think that's the best way to achieve this. By socket i mean unix socket file, but you can also use this over the network.

http://gearman.org/ is also a good alternative as mentioned by @Joshua

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