2

我有两个同时运行的 PHP 脚本。其中之一 ( SleepingScript.php) 调用该sleep函数。如有必要,另一个脚本 ( WakeScript.php) 应该能够唤醒正在休眠的脚本。

我怎样才能做到这一点?

这是一些可以更好地解释这种情况的代码。

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 );
    }
?>
4

1 回答 1

0

这可以使用进程信号 SIGCONT 来通知脚本它需要唤醒来完成。请注意,这需要 php 扩展pcntl并且可能取决于平台(在 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);

这就是它在行动中的样子。第一合一终端:

$ php SleepingScript.php 
93357

并进入第二个终端:

$ php WakeScript.php 93357

回到原来的终端:

$ php SleepingScript.php 
93357
Interrupted by a signal.
Time remaining: 111 seconds, 712678616 nanoseconds.
于 2021-07-16T16:12:24.933 回答