【问题标题】:How can I capture the PID and output of a backgrounded PHP process at the same time?如何同时捕获后台 PHP 进程的 PID 和输出?
【发布时间】:2010-07-16 21:05:38
【问题描述】:

我有一个 PHP 脚本必须使用 exec 在后台启动第二个脚本。父脚本需要捕获这个新进程的 PID,但我还需要捕获子脚本的任何潜在输出,以便将其记录到数据库中。我不能只将子脚本记录到数据库中,因为我还需要捕获致命错误或任何可能表明脚本存在问题的内容。使用 PID 是因为父进程需要能够检查子进程并查看它何时完成。子进程有时会作为 crons 运行,因此这里也不能选择分叉。如果有问题,我不希望有两个执行路径来调试。

这是我的第一个解决方案,它可以捕获输出,但无法获得正确的 PID。

// RedirectToLog.php just reads stdin and logs it to the databse.
$cmd="php child.php </dev/null 2>&1 | php RedirectToLog.php >/dev/null 2>&1 & echo $!";

这里的问题是 $!是在后台启动的最后一个进程的 PID,它最终是 RedirectToLog.php 而不是 child.php。

我的另一个想法是尝试使用 FIFO 文件(管道)。

$cmd1="php RedirectToLog.php </tmp/myFIFO >/dev/null 2>&1 &"
$cmd2="php child.php </dev/null >/tmp/myFIFO 2>&1 & echo $!"

这个不起作用,因为我无法让 RedirectToLog 可靠地使用 fifo,当它这样做时,有时 child.php 无法将 EOF 写入管道,导致两端都在等待另一端,两个进程都会挂起直到一个人被杀。

【问题讨论】:

    标签: php bash


    【解决方案1】:

    使用proc_open 在启动进程时获得完整的 fd 连接。获取proc_open返回的资源,使用proc_get_status获取pid。

    $descriptors = array( ... ); // i suggest you read php.net on this
    $pipes = array();
    $res = proc_open($cmd,$descriptors,$pipes);
    
    $info = proc_get_status($res);
    echo $info['pid'];
    

    我还没有完全掌握您的所有问题,但这应该可以帮助您入门。

    【讨论】:

      【解决方案2】:

      我认为你需要使用
      proc_open &
      proc_get_status

      【讨论】:

        【解决方案3】:

        我猜你真正想要捕获孩子 PID 的唯一原因是监控它。如果是这样,使用proc_open 可能更容易。这样,您基本上可以打开 stdin、stdout 和 stderr 的文件句柄并监视父级的所有内容。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-26
          • 1970-01-01
          • 2021-05-06
          • 2012-02-27
          • 2020-03-24
          • 2021-12-02
          • 1970-01-01
          • 2012-10-04
          相关资源
          最近更新 更多