2

我在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.

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

我究竟做错了什么?

4

1 回答 1

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
    }
}
于 2014-02-25T03:19:49.547 回答