PHP,唤醒正在睡觉的过程

时间:2014-06-12 11:02:35

标签: php sleep wakeup

我有两个同时运行的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 );
    }
?>

1 个答案:

答案 0 :(得分: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.