php - proc_open 离开僵尸进程

标签 php proc-open

以下脚本监视 /dev/shm/test 是否有新文件并实时输出有关它的信息。

问题是当用户关闭浏览器时,inotifywait 进程仍然打开,等等。

有什么办法可以避免这种情况吗?

<?php
$descriptorspec = array(
  0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
  1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
  2 => array("pipe", "a") // stderr is a file to write to
);

$process = proc_open('inotifywait -mc -e create /dev/shm/test/', $descriptorspec, $pipes);

if (is_resource($process)) {

  header("Content-type: text/html;charset=utf-8;");
  ob_end_flush(); //ends the automatic ob started by PHP
  while ($s = fgets($pipes[1])) {
    print $s;
    flush();
  }
  fclose($pipes[1]);
  fclose($pipes[0]);
  fclose($pipes[2]);

  // It is important that you close any pipes before calling
  // proc_close in order to avoid a deadlock
  $return_value = proc_close($process);

  echo "command returned $return_value\n";
}
?>

最佳答案

那是因为 inotifywait 将等待文件 /dev/shm/test/ 发生更改,然后输出诊断标准输出上的标准错误信息和事件信息fgets() 将等待直到它可以读取一行:Reading ends when $length - 已读取 1 个字节(第二个参数),或换行符(包含在返回值中)或 EOF(以先到者为准)。如果没有指定长度,它将继续从流中读取,直到到达行尾。

所以基本上,您应该使用stream_set_blocking($pipes[1], 0) 从子进程的标准输出管道非阻塞 模式读取数据。 ,或手动检查该管道上是否有数据 stream_select() .

此外,您需要使用 ignore_user_abort(true) 忽略用户中止。

关于php - proc_open 离开僵尸进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18828311/

相关文章:

php - Mysql查询插入行不插入行

javascript - 如何在单击输入文本时更改 html 标记元素,以便用户可以编辑评论

PHP proc_open bash 与破折号

PHP:试图让 fgets() 在 CRLF、CR 和 LF 上触发

PHP proc_open 阻止读取 stdout,直到 C 程序终止

java - php proc_open 将输入传递给 java 慢

php - Laravel 5.4 查询生成器使用 groupBy 实现 orderBy

php - yii2:如何使用超棒的字体图标?

php - Laravel 迁移找不到驱动程序

php - 使用 PHP 的 proc_open + bypass_shell 在后台运行可执行文件并检索正确的 PID?