我有一个自定义 php 脚本,它使用 proc_open 打开第三方 perl 脚本。我试图放入一些 pcntl_signal 句柄,以便我可以在中断时优雅地清理。
我能够让我的信号处理程序在更狭窄的测试床上工作,它只是在循环中旋转或其他东西。
但是,当它通过带有 proc_open 的子脚本循环时,CTRL+C 似乎就完全死在那里了。需要明确的是,我的意思是立即完全停止父进程和子进程。并不是说 ctrl+c 被第 3 方子进程捕获,返回并且我的脚本继续。
我在 php 文档中读过,已知信号处理不能很好地与 sleep() 之类的东西配合使用,并认为它可能与 POSIX proc_open 函数类似。仔细查看 SO,似乎有一些类似的帖子提供了一种解决方案,可以根据情况在子进程中移动信号处理或将 restart_syscalls 参数切换为 proc_open。
我尝试将restart_syscalls 参数切换为false,但这对我没有任何好处。
不幸的是,子进程是第 3 方脚本,所以我不熟悉实际代码。在试图解决这个问题以使信号重新传播之前(如果可能的话,甚至是要做的事情),我想知道我的设置是否缺少一些东西,所以我可以只维护我的代码。
我所拥有的看起来像
<?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']);