1

When running a thread, the function registered with pcntl_signal, never gets fired.

<?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();

Then, in the terminal:

# kill -TERM 123

Works fine when there is not a thread:

<?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();

How can I execute some code when I send SIGTERM when running a thread? I'm using: php-5.6.7, pthreads-2.0.10, debian-7

luistar15
  • 163
  • 1
  • 9
  • What is `Thread` class ? Is it part of `pthreads` or is it a homemade class ? Strange that extending from Threads breaks it... Are you sure your code actually runs ? Maybe it crashes at `Task`'s definition, whithout executing your last 3 lines... ? Did you have a look to your `php_error.log` ? – Random May 26 '15 at 15:20

1 Answers1

0

Your main thread is oblivious to the registered signal while trying to join the thread. This is essentially what happens after $task->start().

You have to do two things:

  1. Find a way to let your main thread react to the signal.
  2. Stop the thread from executing, so it won't block exit.

As for 1, you could put your main thread in an endless sleep loop. While PHP is sleeping, it still can react to signals.

And 2, you could kill the thread in your shutdown function.

In Code

After $task->start():

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

Changed shutdown function:

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

Note: Don't use kill in the real world. Find a method to let the thread gracefully terminate on its own.

Apropos Signals

I won't recommend using declare(ticks = 1), it's bad for performance. Try using pcntl_signal_dispatch() instead, after sleep for example.

Kontrollfreak
  • 1,800
  • 12
  • 24