好的,所以我一直在尝试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
的 s 和echo
s (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";
}
所以我ctl-c
在sleep
. 我的结果?
-- 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
的 s 中看到的那样,我有点想也许滴答声的工作方式负责在处理信号之前start
完成功能。我仍然认为可能是这种情况。事实是,我只是不知道。
我确实ticks
在我的程序顶部声明:
declare(ticks = 1);
不立即处理信号给我带来了问题。例如,如果我的函数中有这段代码start
(并且我已经对此进行了测试)怎么办?
$count = 0;
while(true){
count++;
echo "count\n";
sleep(5);
}
即使我的cleanup
函数有一个exit
,我也永远不会达到那个,因为SIGINT
只是把我从 中敲出来sleep
,我继续循环并重新开始sleep
。
所以这是我的问题:signal
处理如何工作PHP
?如何保证当我收到信号时,立即处理?我不只是想要一些可以解决这个问题的代码,我想要一个解释(或至少一个好的链接和摘要)。
PHP版本:5.4.22
操作系统:Ubuntu 12.10