当系统时间改变时,是否可以在 运行 PHP 的长过程中到 capture/handle/detect ?
Is it possible within a long running PHP process to capture/handle/detect when the system time has changed?
好久了reader,第一次发帖...
我在 Ubuntu 16.04 机器上托管了一个长 运行 PHP 7 进程。它以不同的时间间隔执行各种功能;每隔 2 米,有些每隔 15 米,等等。我根据当前纪元时间触发这些函数,与为每个函数维护的 'next_time_to_run' 进行比较。每次执行函数时都会重新计算 next_time_to_run。例如,如果一个函数每 2 分钟执行一次,那么当它被触发时,它只需将当前纪元时间加上 120 即可找到下一个触发时间。
我最近 运行 遇到一个问题,即 NTP 进程显着改变了系统时间,而我的进程是 运行。正如您可能想象的那样,这让我的日程安排变得混乱。 (哦对了,我说的是'tizzy')
我的问题是——是否可以注册 callback/event handler/etc。当系统时间(纪元)改变时会被触发?顺便说一句,系统时钟保持在 UTC。
谢谢哦,伟大而光荣的 Whosebug-hive-mind!
$dothing1time = time() + 120;
$dothing2time = time() + 3600;
while(1) {
$now = time();
if( $now >= $dothing1time ) { dothing1(); $dothing1time = $now + 120; }
if( $now >= $dothing2time ) { dothing2(); $dothing2time = $now + 3600; }
sleep( 30 );
}
<?php
ignore_user_abort ( TRUE );
set_time_limit ( 0 );
$dothing1time = 120;
$dothing2time = 3600;
$now = 0;
$tic = 0;
$toc = 0;
while ( 1 )
{
if ( $now >= $dothing1time )
{
dothing1 ( ++$tic );
$dothing1time = $now + 120;
}
if( $now >= $dothing2time )
{
dothing2 ( ++$toc );
$dothing2time = $now + 3600;
}
sleep( 30 );
$now += 30;
}
function dothing1 ( $tic )
{
file_put_contents ( './dothing1.txt', $tic );
}
function dothing2 ( $toc )
{
file_put_contents ( './dothing2.txt', $toc );
}
?>
为了回答您的具体问题,"No."据我所知,没有 timechanged 事件可以附加监听器。
不幸的是,考虑到您当前的程序架构,我怀疑稳健的解决方案将需要一个单调且均匀增加的时钟——我们的软件和用户-space人们认为理所当然。更不幸的是,没有 PHP 函数可以保证您 "abusing" time()
函数的单调和均匀增加的属性。
但是,有两种可能性。
PHP-native 解决方案可能使用简单循环、休眠和递增计数器的线程。我将线程实例化和其他样板保留为 "exercise for the reader,",但示例线程内核可能是:
while ( $threadAlive ) {
if ( 0 == sleep( 1 ) )
$programMonotonicClock++;
}
您必须进行测试,因为这也可能成为 NTP 时间更改事件的受害者,具体取决于 sleep()
在 PHP 中的实现方式。
另一个可能更稳健的选择是 exploit Linux's jiffy count 为您的程序 "clock." Jiffies 是自计算机首次启动以来的 CPU 时钟周期数.同样,保留进程包装并进一步解析为 "exercise for the reader," 考虑使用此 shell 命令来获取当前的瞬时计数:
$ grep ^jiff /proc/timer_list | head -1
现在,您可以自己检测时间是否发生了变化(通过与程序 counter/jiffy 计数的已知值和最近值进行比较),或者只将程序 counter/jiffy 计数视为您的新计数程序时钟源。
好久了reader,第一次发帖...
我在 Ubuntu 16.04 机器上托管了一个长 运行 PHP 7 进程。它以不同的时间间隔执行各种功能;每隔 2 米,有些每隔 15 米,等等。我根据当前纪元时间触发这些函数,与为每个函数维护的 'next_time_to_run' 进行比较。每次执行函数时都会重新计算 next_time_to_run。例如,如果一个函数每 2 分钟执行一次,那么当它被触发时,它只需将当前纪元时间加上 120 即可找到下一个触发时间。
我最近 运行 遇到一个问题,即 NTP 进程显着改变了系统时间,而我的进程是 运行。正如您可能想象的那样,这让我的日程安排变得混乱。 (哦对了,我说的是'tizzy')
我的问题是——是否可以注册 callback/event handler/etc。当系统时间(纪元)改变时会被触发?顺便说一句,系统时钟保持在 UTC。
谢谢哦,伟大而光荣的 Whosebug-hive-mind!
$dothing1time = time() + 120;
$dothing2time = time() + 3600;
while(1) {
$now = time();
if( $now >= $dothing1time ) { dothing1(); $dothing1time = $now + 120; }
if( $now >= $dothing2time ) { dothing2(); $dothing2time = $now + 3600; }
sleep( 30 );
}
<?php
ignore_user_abort ( TRUE );
set_time_limit ( 0 );
$dothing1time = 120;
$dothing2time = 3600;
$now = 0;
$tic = 0;
$toc = 0;
while ( 1 )
{
if ( $now >= $dothing1time )
{
dothing1 ( ++$tic );
$dothing1time = $now + 120;
}
if( $now >= $dothing2time )
{
dothing2 ( ++$toc );
$dothing2time = $now + 3600;
}
sleep( 30 );
$now += 30;
}
function dothing1 ( $tic )
{
file_put_contents ( './dothing1.txt', $tic );
}
function dothing2 ( $toc )
{
file_put_contents ( './dothing2.txt', $toc );
}
?>
为了回答您的具体问题,"No."据我所知,没有 timechanged 事件可以附加监听器。
不幸的是,考虑到您当前的程序架构,我怀疑稳健的解决方案将需要一个单调且均匀增加的时钟——我们的软件和用户-space人们认为理所当然。更不幸的是,没有 PHP 函数可以保证您 "abusing" time()
函数的单调和均匀增加的属性。
但是,有两种可能性。
PHP-native 解决方案可能使用简单循环、休眠和递增计数器的线程。我将线程实例化和其他样板保留为 "exercise for the reader,",但示例线程内核可能是:
while ( $threadAlive ) { if ( 0 == sleep( 1 ) ) $programMonotonicClock++; }
您必须进行测试,因为这也可能成为 NTP 时间更改事件的受害者,具体取决于
sleep()
在 PHP 中的实现方式。另一个可能更稳健的选择是 exploit Linux's jiffy count 为您的程序 "clock." Jiffies 是自计算机首次启动以来的 CPU 时钟周期数.同样,保留进程包装并进一步解析为 "exercise for the reader," 考虑使用此 shell 命令来获取当前的瞬时计数:
$ grep ^jiff /proc/timer_list | head -1
现在,您可以自己检测时间是否发生了变化(通过与程序 counter/jiffy 计数的已知值和最近值进行比较),或者只将程序 counter/jiffy 计数视为您的新计数程序时钟源。