我有两个同时运行的PHP脚本。其中一个(SleepingScript.php
)调用sleep
函数。另一个脚本(WakeScript.php
)应该能够在必要时唤醒睡眠脚本。
我怎样才能做到这一点?
以下是一些可以更好地解释情况的代码。
<?php
$myPid = getmypid();
/* save $myPid to database or file */
sleep( 120 );
/* other statements executed after 2 minutes or when woken up by WakeScript */
?>
<?php
/* ... */
if( $wakeUpNeeded ) {
$pid = readSavedPid();
wake( $pid );
}
?>
答案 0 :(得分:0)
这可以使用进程信号 SIGCONT 通知脚本它需要唤醒来完成。请注意,这需要 php 扩展 pcntl 并且可能依赖于平台(在 macOS Big Sur 上测试):
<?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.";
}
<?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);
这是它的实际效果。第一终端:
$ php SleepingScript.php
93357
然后去第二个终端:
$ php WakeScript.php 93357
回到原来的终端:
$ php SleepingScript.php
93357
Interrupted by a signal.
Time remaining: 111 seconds, 712678616 nanoseconds.