好的,我一直在尝试让 Process Signals
与 PHP
脚本一起工作。我遇到了很多问题,有些情况下我不确定发生了什么,而且我觉得文档并没有很好地解释清楚。
所以假设我按照 注册信号 的示例进行操作:
<?php
// tick use required as of PHP 4.3.0
declare(ticks = 1);
// signal handler function
function sig_handler($signo)
{
switch ($signo) {
case SIGTERM:
// handle shutdown tasks
exit;
break;
case SIGHUP:
// handle restart tasks
break;
case SIGUSR1:
echo "Caught SIGUSR1...\n";
break;
default:
// handle all other signals
}
}
echo "Installing signal handler...\n";
// setup signal handlers
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");
// or use an object, available as of PHP 4.3.0
// pcntl_signal(SIGUSR1, array($obj, "do_something"));
echo"Generating signal SIGTERM to self...\n";
// send SIGUSR1 to current process id
posix_kill(posix_getpid(), SIGUSR1);
echo "Done\n";
?>
然而,在我的
sig_handler
函数中,我在结尾处添加了一个 exit(1)
。那么 echo "Done\n";
仍然会执行吗?我尝试过类似的操作,虽然是在类结构中,但只有在我的 sig_handler
被调用之前才能实现。我的类
__construct
调用函数 registerSignals
:private function registerSignals(){
if(function_exists("pcntl_signal")){
//call_user_func([$this, "sigintCleanup"]);
pcntl_signal(SIGINT, [$this, "sigintCleanup"]);
pcntl_signal(SIGTERM, [$this, "sigtermCleanup"]);
pcntl_signal(SIGHUP, [$this, "sighupCleanup"]);
pcntl_signal(SIGUSR1, [$this, "sigusr1Cleanup"]);
}
}
protected function sigintCleanup(){
echo "In SIGINT cleanup\n";
$this->cleanup();
}
protected function sigtermCleanup(){
echo "In SIGTERM cleanup\n";
$this->cleanup();
}
protected function sighupCleanup(){
echo "In SIGHUP cleanup\n";
$this->cleanup();
}
protected function sigusr1Cleanup(){
echo "In SIGUSR1 cleanup\n";
$this->cleanup();
}
protected function cleanup(){
echo "Shutting down\n";
exit(1);
}
在测试这个过程中,我会进行一些简单的sleep
和echo
操作(start
只是在构建和信号注册完成后调用的一个函数):
function start(){
echo "-- Testing the test script --\n";
sleep(10000);
echo "given how ticks work, this might not be called...\n";
echo "\nAfter sleep... this should not be executed if there was a signal interrupt.\n";
}
所以我在
sleep
过程中使用 ctl-c
。我的结果?-- Testing the test script --
^Cgiven how ticks work, this might not be called...
After sleep... this should not be executed if there was a signal interrupt.
In SIGINT cleanup
Shutting down
正如您可以从我的
echo
中看到的那样,我有点想知道 ticks的工作方式是否负责在处理信号之前完成start
函数。我仍然认为这可能是事实。事实上,我不知道。我在程序顶部声明了
ticks
:declare(ticks = 1);
不立即处理信号对我造成了问题。例如,如果我在我的start
函数中有这段代码(我已经测试过了),会发生什么?
$count = 0;
while(true){
count++;
echo "count\n";
sleep(5);
}
即使我的
cleanup
函数有一个exit
,由于SIGINT
只是将我从sleep
中唤醒,我永远不会到达那里,然后我继续循环并开始再次sleep
。所以我的问题是:在PHP中,signal
处理是如何工作的?我怎样才能保证当我收到一个信号时,它会立即被处理?我不仅想要一些可以解决这个问题的代码,我还想要一个解释(或至少是一个好的链接和摘要)。PHP版本:5.4.22,操作系统:Ubuntu 12.10。