Php 使用自定义SIGTERM处理程序时的Segfaulting
我有一个无限期运行的PHP脚本,我正在尝试使它在收到SIGTERM信号时能够正常关闭。此脚本是大型Symfony2代码库的一部分,因此“脚本”实际上是由命令启动的服务。基本上,我在服务类Php 使用自定义SIGTERM处理程序时的Segfaulting,php,symfony,signals,Php,Symfony,Signals,我有一个无限期运行的PHP脚本,我正在尝试使它在收到SIGTERM信号时能够正常关闭。此脚本是大型Symfony2代码库的一部分,因此“脚本”实际上是由命令启动的服务。基本上,我在服务类$shouldBeAlive中有一个布尔值。我有一个while(true)循环,它检查$shouldBeAlive在每次迭代开始时是否仍然为true。然后在while(true)循环开始之前设置一个信号处理程序,如果抛出SIGTERM,则将$shouldBeAlive设置为false,这样循环将完成当前迭代,然后
$shouldBeAlive
中有一个布尔值。我有一个while(true)
循环,它检查$shouldBeAlive
在每次迭代开始时是否仍然为true。然后在while(true)
循环开始之前设置一个信号处理程序,如果抛出SIGTERM,则将$shouldBeAlive
设置为false,这样循环将完成当前迭代,然后在下一次迭代开始时立即退出
在我对信号和其他东西的理解中,所有这些都应该很好。但是,每次我向php进程发送一个SIGTERM(我使用kill
)时,就会收到一条消息Segmentation fault:11
。我曾尝试使用Xdebug跟踪来查找问题的根源,但我无法从中找出一个明显的问题(而且,Xdebug生成的跟踪文件是8-10MB)
以下是我的服务类的简化版本:
class WorkerService extends AbstractService
{
private $shouldBeAlive;
// called by the constructor of this class
protected function setup()
{
$this->shouldBeAlive = false;
}
// called when my command wants to make the work begin
public function go()
{
$this->shouldBeAlive = true;
// set signal handler to `$this->handleSignal($signo)`
assert(pcntl_signal(SIGTERM, [$this, "handleSignal"]));
$this->work();
}
public function handleSignal($signo)
{
// make the worker terminate on next loop completion
$this->shouldBeAlive = false;
// restore the default handler for this signal
assert(pcntl_signal($signo, SIG_DFL));
echo "Signal received, shutting down gracefully... (send signal again to force immediate shutdown)";
return;
}
public function work()
{
while (true) {
// make PHP fire any waiting signals
pcntl_signal_dispatch();
// break out of the loop if we're supposed to be dead
if (!$this->shouldBeAlive) break;
// ...
// I'm omitting the actual loop logic. Basically, it makes some
// HTTP requests, sometimes starts another process with proc_open(),
// and eventually it'll sleep for a couple seconds and continue.
}
}
}
似乎我的handleSignal($signo)方法根本就没有被调用过,因为对它的任何调整都不能解决这个问题。我还尝试使用
declare(ticks=1)在go()方法中调用code>,而不是调用pcntl_signal_dispatch()代码>在while(true)循环中,它仍然会出现故障(而且,按照我的理解,这样做毫无意义)。有人知道我可能遗漏了什么或误解了什么吗?分段错误:11——听起来php实际上崩溃了。尝试将回音移到信号处理程序的开头,看看处理程序中是否有导致php崩溃/错误的操作。@Stian Skjelstad已经有一段时间了,但我想我已经尝试过了,并且发现该函数从未被调用过。