未收到pcntl_signal信号

时间:2014-02-08 17:21:26

标签: php pthreads posix pcntl

我遇到一些问题,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.

永远不会调用信号处理程序。

我做错了什么?

1 个答案:

答案 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
    }
}