Skip to content
Advertisement

PHP, wake up process which is sleeping

I have two PHP scripts which are running at the same time. One of them (SleepingScript.php) calls the sleep function. The other script (WakeScript.php) should be able to wake up the sleeping script if necessary.

How can I achieve this?

Here is some code that explains better the situation.

SleepingScript.php

<?php
   $myPid = getmypid();
   /* save $myPid to database or file */
   sleep( 120 );
   /* other statements executed after 2 minutes or when woken up by WakeScript */
?>

WakeScript.php

<?php
    /* ... */
    if( $wakeUpNeeded ) {
      $pid = readSavedPid();
      wake( $pid );
    }
?>

Advertisement

Answer

This can be done using the process signal SIGCONT to inform the script it needs to wake up. Note that this requires the php extension pcntl and may be platform dependent (tested on macOS Big Sur):

SleepingScript.php

<?php

if (!extension_loaded('pcntl')) {
    echo 'Unable to wake up!n';
} else {
    // While we aren't doing anything with the CONT signal, we need
    // it to be handled so that the process can wake up from sleep
    pcntl_signal(SIGCONT, function () {});
}

// Save this to file, redis, or something else
echo posix_getpid() . "n";

// Sometimes time_nanosleep isn't available on your platform
// If it's not, you'll need to substitute using sleep/usleep and maybe hrtime
$seconds = 120;
$nanoseconds = 0;
$nano = time_nanosleep($seconds, $nanoseconds);

if ($nano === true) {
    echo "Slept for $seconds seconds, $nanoseconds nanoseconds.n";
} elseif ($nano === false) {
    echo "Sleeping failed.n";
} else {
    echo "Interrupted by a signal.n";
    echo "Time remaining: {$nano['seconds']} seconds, {$nano['nanoseconds']} nanoseconds.";
}

WakeScript.php

<?php

// Get saved pid. This could be from file, redis, or something else.
// Here we're going to use the first argument for ease
$pid = (int)$argv[1];

// While normally used to kill a process, posix_kill really just sends a signal.
// We'll send SIGCONT to wake up the other script
posix_kill($pid, SIGCONT);

And here’s what it looks like in action. First in one terminal:

$ php SleepingScript.php 
93357

And going to a second terminal:

$ php WakeScript.php 93357

And back to the original terminal:

$ php SleepingScript.php 
93357
Interrupted by a signal.
Time remaining: 111 seconds, 712678616 nanoseconds.
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement