PHP IPC Signal Example
Mai 24th, 2013
There are several pitfalls when using POSIX signal handling with php. The following example should help to get around them.
The example forks a child process and afterwards sends the SIGTERM
signal to the child. I’ll guide you through the important sections:
<?php
declare(ticks=1);
Declare ticks
is essential for signal handling in PHP. If not declared, signals will not being passed to the script.
$term = FALSE;
Define a flag which will later being used to determine if SIGTERM
has been arrived.
function handler() {
global $term;
$term = TRUE;
}
The signal handler method. The handler should contain as less actions as possible. This is a general advice for signal handlers (not just for PHP). If the signal handler contains much actions and will take long to process, it may happen that following signals get blocked.
pcntl_signal(SIGTERM, 'handler');
Register the signal handler for SIGTERM
$pid = pcntl_fork();
For current process
if($pid === 0) {
echo "child: started\n";
while(TRUE) {
if($term) {
echo "child: exit\n";
exit(2);
}
usleep(100000);
}
In the child process $pid
will be „ after forking. The code above is the child code. It runs in a infinite loop and checks if the $term
flag was set. If so, it terminates itself.
It follows the father’s code:
} else {
echo "father: started $pid\n";
// kill the child
echo "father: send SIGTERM\n";
posix_kill($pid, SIGTERM);
Use posix_kill()
to send SIGTERM
to child.
$pid = pcntl_waitpid($pid, $status);
echo "father: child exited $status\n";
}
Now wait until the child has exited to grab it’s return value.
Here comes the complete solution:
<?php
declare(ticks=1);
$term = FALSE;
function handler() {
global $term;
$term = TRUE;
}
pcntl_signal(SIGTERM, 'handler');
$pid = pcntl_fork();
if($pid === 0) {
echo "child: started\n";
while(TRUE) {
if($term) {
echo "child: exit\n";
exit(2);
}
usleep(100000);
}
} else {
echo "father: started $pid\n";
// kill the child
echo "father: send SIGTERM\n";
posix_kill($pid, SIGTERM);
// wait until child exit
$pid = pcntl_waitpid($pid, $status);
echo "father: child exited $status\n";
}
Leave a Reply