我遇到一些问题,pcntl_signal
没有收到另一个进程发送的信号。我有一个脚本,它会分叉一个新的进程,激活2个后台线程然后循环控制器(主)线程,直到它收到一个停止信号(SIGUSR1)但是从未收到信号。这是我的线程代码(只是为了演示而登录循环)。
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";
在另一个过程中,我们发出如下信号:
posix_kill($pid, SIGUSR1); // $pid being the $child_pid from the other process.
永远不会调用信号处理程序。
我做错了什么?
答案 0 :(得分:0)
我认为你在handleSignal()中只有一点逻辑错误,要让你的循环在run()中停止你应该设置running = false。
例如:
function handleSignal($signo) {
echo "Received signal $signo";
switch ($signo) {
case SIGUSR1:
$this->running = false;
break;
default:
// handle all other signals
}
}