オブジェクトメソッドに SIGTERM ハンドラを設定しようとしていたのですが、わからないことがありました。次のコードを考えてみましょう。
function _log($msg, $arr=array()){
$str = vsprintf($msg, $arr);
fprintf(STDERR, "$str\n");
}
class A
{
public static $running = true;
public function start()
{
while($this->run()) sleep(2);
}
public function run()
{
_log('run called');
if( ! self::$running)
{
return false;
}
sleep(3);
_log('run end');
return true;
}
public function signal_handler($signo){
_log("Caught a signal %d", array($signo));
switch ($signo) {
case SIGINT:
A::$running = false;
break;
default:
fprintf(STDERR, "Unknown signal ". $signo);
}
}
}
$a = new A;
if(version_compare(PHP_VERSION, "5.3.0", '<')){
declare(ticks = 1);
}
pcntl_signal(SIGINT, array($a, "signal_handler"));
if(version_compare(PHP_VERSION, "5.3.0", '>=')){
pcntl_signal_dispatch();
_log("Signal dispatched");
}
//while($a->run()) sleep(2);
$a->start();
$a->start() を呼び出すと、SIGTERM は sleep() を中断するだけで、ハンドラは呼び出されません。しかし、実際には以前と同じことである while($a->run()) sleep(2); を試すと、ハンドラーが呼び出され、期待どおりに実行が停止します。誰でもこの動作を説明できますか?