【问题标题】:shutting down a php process using pcntl_signal when running a thread运行线程时使用 pcntl_signal 关闭 php 进程
【发布时间】:2015-06-25 00:42:00
【问题描述】:

在运行线程时,使用pcntl_signal 注册的函数永远不会被触发。

<?php
declare(ticks = 1);

class Task extends Thread {
    public function run () {
        while (1) sleep(1); // run forever
    }
}

function shutdown () { // never runs :(
    echo "Good bye!\n"; exit;
}

pcntl_signal(SIGTERM, 'shutdown');

$task = new Task;
$task->start();

然后,在终端中:

# kill -TERM 123

在没有线程时可以正常工作:

<?php
declare(ticks = 1);

class Task {
    public function run () {
        while (1) sleep(1); // run forever
    }
}

function shutdown () {
    echo "Good bye!\n"; exit;
}

pcntl_signal(SIGTERM, 'shutdown');

$task = new Task;
$task->run();

当我在运行线程时发送 SIGTERM 时如何执行一些代码? 我正在使用:php-5.6.7、pthreads-2.0.10、debian-7

【问题讨论】:

  • Thread 类是什么?它是pthreads 的一部分还是自制课程?奇怪的是,从 Threads 扩展会破坏它......你确定你的代码真的运行了吗?也许它在Task 的定义处崩溃,而没有执行你的最后3 行......?你看过你的php_error.log 吗?

标签: php pthreads pcntl sigterm


【解决方案1】:

您的主线程在尝试加入线程时忽略了注册信号。这基本上是$task-&gt;start() 之后发生的事情。

你必须做两件事:

  1. 想办法让主线程对信号做出反应。
  2. 停止线程执行,这样它就不会阻塞exit

至于 1,您可以将您的主线程置于无限的sleep 循环中。虽然 PHP 是 sleeping,但它仍然可以对信号做出反应。

还有 2,您可以在 shutdown 函数中使用 kill 线程。

在代码中

$task-&gt;start()之后:

for (;;) {
    sleep(PHP_INT_MAX);
}

更改shutdown函数:

function shutdown ()
{
    echo "Good bye!\n";
    $GLOBALS['task']->kill();
    exit;
}

注意:不要在现实世界中使用kill。找到一种方法让线程自行优雅地终止。

适当的信号

我不建议使用declare(ticks = 1),这对性能不利。尝试改用pcntl_signal_dispatch(),例如在sleep 之后。

【讨论】:

    猜你喜欢
    • 2017-03-13
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 2021-04-12
    • 2017-05-31
    相关资源
    最近更新 更多