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.