Возможно ли в течение длительного процесса PHP захватить / обработать / обнаружить, когда системное время изменилось? - PullRequest
0 голосов
/ 11 января 2019

Долгое время читатель, первый постер ...

У меня есть длительный процесс PHP 7, размещенный на машине с Ubuntu 16.04. Он выполняет различные функции с различными интервалами; что-то каждые 2 м, а некоторые - каждые 15 м и т. д. Я запускаю эти функции на основе текущего времени эпохи, сравнивая «next_time_to_run», поддерживаемое для каждой функции. Next_time_to_run пересчитывается каждый раз, когда выполняется функция. Например, если функция выполняется каждые 2 минуты, то при запуске она просто добавляет 120 к текущему времени эпохи, чтобы найти следующее время запуска.

Недавно я столкнулся с проблемой, когда процесс NTP довольно резко изменил системное время во время работы моего процесса. Как вы можете себе представить, это привело меня в замешательство. ( о да, я сказал 'tizzy' )

У меня такой вопрос - можно ли зарегистрировать обратный вызов / обработчик событий / и т.д. что будет срабатывать при изменении системного времени (эпохи)? Кстати, системные часы поддерживаются в UTC.

Спасибо, о-о-о-о-великолепно, StackOverflow-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 );
}

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Чтобы ответить на ваш конкретный вопрос, «Нет». Насколько мне известно, нет события с изменением времени , к которому вы могли бы присоединить слушателя.

К сожалению, учитывая вашу текущую программную архитектуру, я подозреваю, что надежное решение потребует монотонно и равномерно увеличивающихся часов - что-то, что мы, пользователи программного обеспечения и пользователя, принимаем как должное. Кроме того, к сожалению, нет функции PHP, которая гарантирует монотонные и равномерно растущие свойства, для которых вы «злоупотребляли» функцией time().

Однако есть несколько возможностей.

  • PHP-нативное решение может использовать поток, который просто зацикливает, спит и увеличивает счетчик. Я оставляю создание потока и другой шаблон как «упражнение для читателя», но примерное ядро ​​потока может быть:

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

    Вам придется протестировать, поскольку это тоже может стать жертвой события изменения времени NTP, в зависимости от того, как sleep() реализован в PHP.

  • Другим, возможно, более надежным вариантом будет использовать подсчет jiffy в Linux для вашей программы "clock". Jiffies - это количество тактов ЦП с момента первой загрузки компьютера. Опять же, оставляя обертки процесса и дальнейший синтаксический анализ как «упражнение для читателя», рассмотрите эту команду оболочки, чтобы получить текущий счетчик jiffy:

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

Теперь вы можете сами определить, изменилось ли время (сравнивая с вашими известными и недавними значениями счетчика / числа jiffy вашей программы), или просто обработать счетчик / счетчик jiffy программы в качестве нового источника часов программы.

0 голосов
/ 11 января 2019
<?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 );
}

?>
...