EvPeriodic 观察器根据 offset
、interval
和 reschedule_cb
参数以不同的模式工作。
绝对计时器 。在此模式下 interval
= 0
,reschedule_cb
= null
。该计时器仅在墙钟时间 offset
处触发,并且不会重复。它不会在发生时间跳跃时调整,也就是说,如果它将在2014 年 1 月 1 日 运行,那么当系统时间达到或超过此时间时它将运行。
重复间隔计时器 。在此模式下 interval
> 0
,reschedule_cb
= null
;观察器将始终安排在下一个 offset
+ N
* interval
时间(对于某些整数 N
)超时,然后重复,而不管发生任何时间跳跃。
这可以用于创建不会相对于系统时间漂移的计时器
<?php
$hourly = EvPeriodic(0, 3600, NULL, function () {
echo "每小时一次\n";
});
?>
3600
秒,而只是表示当系统时间显示一个完整的小时(UTC)时,将调用回调。
EvPeriodic 会尝试在此模式下在下一个可能的 time = offset
(mod
interval
)时间运行回调,而不管发生任何时间跳跃。
手动重新安排模式 。在此模式下,reschedule_cb
是一个 callable 。
interval
和 offset
都被忽略。相反,每次周期性观察器被调度时,重新安排回调(reschedule_cb
)将被调用,观察器作为第一个参数,当前时间作为第二个参数。
此回调绝不能停止或销毁此观察器或任何其他周期性观察器,并且绝不能调用任何事件循环函数或方法。要停止它,请返回 1e30
并在之后停止它。可以使用 EvPrepare 观察器来完成此任务。
它必须根据传递的时间值(即大于或等于第二个参数的最小时间值)返回下一个触发时间。它通常会在回调被触发之前被调用,但也可能在其他时间被调用。
示例 #1 使用重新安排回调
<?php
// 每 10.5 秒滴答一次
function reschedule_cb ($watcher, $now) {
return $now + (10.5. - fmod($now, 10.5));
}
$w = new EvPeriodic(0., 0., "reschedule_cb", function ($w, $revents) {
echo time(), PHP_EOL;
});
Ev::run();
?>