我有一个自定义的PHP脚本,使用proc_open打开第三方perl脚本。我试图放入一些pcntl_signal句柄,这样我就可以在中断时优雅地进行清理。
我能让我的信号处理程序在更狭窄的测试床上工作,它只是在一个循环或其他东西中旋转。
然而,当它循环遍历子脚本w / proc_open时,CTRL + C似乎完全就在那里死了。要明确我的意思是完全立即停止父子进程。它是不,好像ctrl + c被第三方子进程捕获,返回并且我的脚本继续。
我已经在php文档中读到了它已知的信号处理与sleep()之类的东西不能很好地兼容并且认为它可能与POSIX proc_open函数类似。看看SO似乎有一些类似的帖子,可以解决在子进程中移动信号处理或将restart_syscalls参数切换到proc_open,具体取决于具体情况。
我尝试将restart_syscalls param切换为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']);
答案 0 :(得分:0)
如果您希望在孩子死亡时收到通知,您也应该听SIGCHLD。 我认为您也可以安全地放置在轮询周期内的sleep(1),以减少繁忙的工作。