I'm having some problems with pcntl_signal
not receiving a signal sent from another process. I have a script that forks a new process, fires up 2 background threads and then loops the controller (main) thread until it receives a stop signal (SIGUSR1) but the signal is never received. Here's my thread code (simply logs in a loop for demo purposes).
declare(ticks = 100);
class Background1 extends Thread {
public function __construct() {
}
public function run() {
echo "Starting Background 1 thread";
while( $this->running ) {
echo "Background 1 looping...\n";
sleep(5);
}
echo "Exiting Background 1 thread";
}
public function play() {
$this->running = true;
$this->start();
}
public function stop() {
$this->notify();
$this->join();
}
}
class Background2 extends Thread {
public function __construct() {
}
public function run() {
echo "Starting Background 2 thread";
while( $this->running ) {
echo "Background 2 looping...\n";
sleep(5);
}
echo "Exiting Background 2 thread";
}
public function play() {
$this->running = true;
$this->start();
}
public function stop() {
$this->running = false;
$this->join();
}
}
class ControllerThread {
function __construct() {
}
function handleSignal($signo) {
echo "Received signal $signo";
switch ($signo) {
case SIGUSR1:
$this->running = true;
break;
default:
// handle all other signals
}
}
public function run() {
pcntl_signal(SIGUSR1, array(&$this, "handleSignal"), true);
$this->running = true;
while( $this->running ) {
echo "Starting controller loop";
$background1 = new Background1;
$background2 = new Background2;
$background1->play();
$background2->play();
while( $this->running ) {
echo "Controller looping...";
sleep(5);
pcntl_signal_dispatch();
}
$background1->stop();
$background2->stop();
echo "Exiting controller loop";
}
}
}
date_default_timezone_set('Europe/London');
$child_pid = pcntl_fork();
if ($child_pid) {
pcntl_waitpid($child_pid, $status);
$child_pid = posix_getpid();
echo "PID running: $child_pid";
exit;
}
echo "Starting main app thread";
$controller = new ControllerThread();
$controller->run();
echo "Exiting main app thread";
In a separate process we signal the other process like this:
posix_kill($pid, SIGUSR1); // $pid being the $child_pid from the other process.
The signal handler is never called.
What am I doing wrong?