当前位置: 首页 > 知识库问答 >
问题:

带proc_open的php pcntl_signal

曾修真
2023-03-14

我有一个自定义的php脚本,它使用proc_open打开第三方perl脚本。我试图放入一些pcntl_signal句柄,以便我可以在中断时优雅地清理。

我能够让我的信号处理程序在更狭窄的测试台上工作,它只是在循环中旋转或其他东西。

但是,当它循环使用带有proc_open的子脚本时,CTRL C似乎就在那里完全死亡。需要明确的是,我的意思是完全立即停止父进程和子进程。这并不是说ctrl c被第三方子进程捕获,返回并且我的脚本继续。

我在php文档中读到,众所周知,信号处理不能很好地处理像sleep()这样的东西,并认为它可能与POSIX proc_open函数类似。综上所述,似乎有一些类似的帖子提供了一种解决方案,要么在子进程中移动信号处理,要么根据情况将restart_syscalls param切换为proc_open。

我试图将restart_syscalls参数切换为false,但这对我没有任何好处。

不幸的是,子进程是第三方脚本,所以我不熟悉实际的代码。在尝试将信号传播回来之前(如果可能的话),我想知道我的设置是否缺少了什么,这样我就可以只维护我的代码。

我所拥有的看起来像

<?php

declare(ticks=1);

class signalHandler{

    public static function handle($signal){
        throw new KillException("Received Kill signal $signal", $signal);
    }

}
pcntl_signal(SIGINT,array('signalHandler','handle'));

然后稍后,调用实际的子进程:

$childCmd = "thirdPartyScript.pl";

// Set up how we'll interact with the IO file handlers of the process
$descriptors = Array(
    0 => Array('file', '/dev/null', 'r'), // Process will read from /dev/null
    1 => Array('pipe', 'w'), // Process will write to STDOUT pipe
    2 => Array('pipe', 'w')  // Process will write to STDERR pipe
);

// Start the process
$childProc = proc_open($childCmd, $descriptors, $pipes);

// Check the status of the backup every second...
$streamContents = '';

stream_set_blocking($pipes[2], 0);
do {
    $streamContents .= stream_get_contents($pipes[2]);

    if( ! ( $childStatus = proc_get_status($childProc) ) ) {
        throw new Exception("Error: Unable to retrieve status on child process.");
    }


} while ($childStatus['running']);

共有1个答案

岳景明
2023-03-14

如果你想在你的孩子去世时得到通知,你也应该听SIGCHLD。我认为你也可以安全地把例如睡眠(1)放在轮询周期内,以减少繁忙的工作。

 类似资料:
  • 原始问题(在CTRL C上向孩子发送SIGTERM,父母应该等待它关闭)。请参阅下面的更新! 我有一个PHP脚本(见下文)启动一个进程并跟踪它的输出。这个过程一直运行,直到我通过按CTRL+C或者向PHP脚本(pid)发送一个SIGTERM信号来请求PHP停止。此时,PHP决定立即终止由proc_open启动的进程,而不是优雅地关闭它,并在关闭自己之前等待它,我该如何实现这一点? 我尝试了一些东西

  • 我在个人Ubuntu服务器机器中有以下PHP代码: 我从PHP得到这样的回答: 很明显,我想改变活跃的用户,但是有没有办法从php中做到这一点?

  • 我使用以下代码打开proc_open进程,并将句柄和管道保存到文件中: 在第二个时刻,我需要从文件中检索这个文件句柄,我使用了这个代码: 当然,在这一点上,如果我试图关闭管道,我会得到一个错误,资源预期,整数给定。 我怎样才能让这工作?(注意:这是我正在寻找的解决方案) 但是或者,我也可以得到进程的pid,然后使用这个pid来停止或杀死进程,或者对进程做任何其他事情,但是管道呢?如何读取/写入或保

  • 作为一个新的主题,我已经建立了一个Ubuntu 12网络服务器,根目录是 /var/www/包含我的脚本index.php和一个名为“减少”的子目录,包含一个二进制文件(一个计算机代数系统,文件名也是“减少””)。 使用ssh,我可以作为root用户和我的非管理员用户帐户以及cd登录到/var/www/目录,并通过执行“/reduce/reduce”启动二进制文件。但是,如果我对索引做同样的事情。

  • 我有一个脚本,它使用php-l检查php文件中的语法错误。它在windows中工作正常,但在Linux中输出不正确: 文件exec_ip的内容。正在检查语法错误的php是(它有要检查的语法错误): 剧本是: 窗口(WAMP){更正}中的结果: LINUX(Centos/cPanel){未知输出}中的结果: 请有人帮助我,并告诉我为什么它在linux生产服务器中给出了不正确的输出。我也尝试过用she