Reputation: 1071
I'm writing a daemon in PHP 5.6. So far, it is basically a Daemon
class with a mainLoop()
method that has an infinite loop. In each iteration, the mainLoop executes a series of steps.
I need it to implement a "graceful kill" mechanism: if a SIGINT or SIGTERM arrive, the daemon must complete the current step of the current iteration before dying.
My idea is to use a static variable Daemon::CONTINUE
TRUE by default; when a SIGINT or SIGTERM arrives, it is set to FALSE.
In each iteration, before passing to the next step the daemon checks if self::CONTINUE
has switched to FALSE and, if it has, it returns.
I know that the way to do this is to use pcntl_signal
. It seems that I can either use it with declare(ticks=1)
or with pcntl_signal_dispatch()
, but I'm not sure about the difference.
Does declare(ticks=1)
make the process check for the arrival of signals after each tick, whereas pcntl_signal_dispatch()
explicitly checks the signals only when I call it?
These are snippets of the two ways I described before. Are they both correct? Which one should I use?
Way 1
<?php
declare(ticks=1) {
pcntl_signal(SIGINT, function($signo) {Daemon::CONTINUE = FALSE;});
pcntl_signal(SIGTERM, function($signo) {Daemon::CONTINUE = FALSE;});
}
public class Daemon {
public static $CONTINUE = TRUE;
function mainLoop() {
...
if (self::CONTINUE === FALSE)
return;
...
}
}
Way 2
<?php
pcntl_signal(SIGINT, function($signo) {Daemon::CONTINUE = FALSE;});
pcntl_signal(SIGTERM, function($signo) {Daemon::CONTINUE = FALSE;});
public class Daemon {
public static $CONTINUE = TRUE;
function mainLoop() {
...
pcntl_signal_dispatch();
if (self::CONTINUE === FALSE)
return;
...
}
}
Thanks for your support.
Upvotes: 2
Views: 930
Reputation: 1071
Ok, after some testing and debugging I tried both solutions. I'll leave here my observations in case somebody encounters my same issues.
It seems that the way 1 with declare(ticks=1) does not work; I can not understand why.
The way 2 with pcntl_signal_dispatch(), on the contrary, seems to work nice.
After deeper research, I think that the way 2 is the best one for my case anyway.
In fact, declare(tick=1), if it worked, would run the pcntl_signal on each tick, roughly corresponding to the execution of each code line.
This can potentially degradate the performances.
On the contrary, apparently pcntl_signal_dispatch) just handles pending signals when it is called, so it should be lighter on performances.
Upvotes: 2