在长时间运行的PHP过程中,是否可以捕获/处理/检测系统时间是否已更改?

时间:2019-01-10 23:44:58

标签: php linux ubuntu ntp

长期阅读者,第一次海报...

我在Ubuntu 16.04机器上托管了一个长时间运行的PHP 7进程。它以不同的时间间隔执行各种功能;每隔2m就有东西,每隔15m等等。我根据当前纪元时间触发这些函数,然后比较每个函数维护的“ next_time_to_run”。每次执行该功能时,都会重新计算next_time_to_run。例如,如果每隔2分钟执行一次功能,则在触发该功能时,只需将当前时间加120,即可找到下一个触发时间。

我最近遇到了一个问题,当我的进程运行时,NTP进程极大地改变了系统时间。您可能会想到,这使我的日程安排变得头昏眼花。 (哦,是的,我说'tizzy'

我的问题是-是否可以注册回调/事件处理程序/等。更改系统时间(纪元)会触发什么?顺便说一句,系统时钟保持在UTC。

感谢哦,伟大和光荣的StackOverflow,蜂巢的思想!

$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 );
}

2 个答案:

答案 0 :(得分:0)

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

?>

答案 1 :(得分:0)

要回答您的特定问题,“不。”据我所知,没有可以附加侦听器的 timechanged 事件。

不幸的是,考虑到您当前的程序体系结构,我怀疑一个健壮的解决方案会需要一个单调且一致地增加的时钟,这是我们软件和用户空间人员认为理所当然的。更不幸的是,没有PHP函数可以保证您正在“滥用” time()函数的单调且一致增加的属性。

但是,有两种可能。

  • PHP原生解决方案可能使用一个简单地循环,休眠和增加计数器的线程。我将线程实例化和其他样板保留为“读者练习”,但示例线程内核可能是:

    while ( $threadAlive ) {
      if ( 0 == sleep( 1 ) )
        $programMonotonicClock++;
    }
    

    您必须进行测试,因为这也可能成为NTP时间更改事件的受害者,具体取决于sleep()在PHP中的实现方式。

  • 另一个可能更强大的选择是将exploit Linux's jiffy count设置为您的程序“时钟”。 Jiffies是自计算机首次启动以来的CPU时钟周期数。再次,保留过程包装并进一步解析为“读者练习”,请考虑以下shell命令以获取当前的计数:

    $ grep ^jiff /proc/timer_list | head -1
    

现在,您可以检测时间是否已更改(通过与程序计数器/抖动计数的已知值和最近值进行比较),或仅将程序计数器/抖动计数视为新的程序时钟源。