2

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 );
    }
?>
woseth
  • 175
  • 1
  • 6
  • Not a duplicate but very closely related [how-can-i-stop-php-sleep...](http://stackoverflow.com/questions/1617412/how-can-i-stop-php-sleep-affecting-my-whole-php-code) – EvilEpidemic Jun 12 '14 at 11:11
  • there is no easy way of waking a 'sleeping' script directly. However, imagine the 'sleeping' script 'wakes up every second' and checks to see if something exists, like a file? e.g. Create a file. Check the file exists in the sleeping script every second. Delete the file when you want the script to 'wake up'. Lots of other ways that are cheaper. It is the method that is useful. – Ryan Vincent Jun 12 '14 at 11:52

1 Answers1

0

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.
jgawrych
  • 3,322
  • 1
  • 28
  • 38