Pull to refresh

Правильный способ реализации таймеров и таймаутов.

Reading time 1 min
Views 4.1K
А вы знаете, что в 99% приложений и абсолютно всех CPAN-модулях таймеры и таймауты реализованы неправильно? Не верите? Правильно не верите! Есть, есть один CPAN-модуль, с корректной реализацией таймеров: EV. :) (Кстати, это, похоже, единственный CPAN-модуль из всех, реализующих event loop, который знает о проблеме использования fork вместе с event loop, описывает её в документации и даже пытается как-то решать!)

Проблема в том, что для реализации таймеров и таймаутов используются функции, возвращающие текущее время. А текущее время может быть изменено в любой момент в любую сторону на любую величину — админом или NTP-демоном. Поэтому получается так, что, например, таймаут установленный программой на 30 секунд, может сработать либо через 2 секунды, либо через пару суток — смотря как изменится текущее время после установки таймаута (а в особо запущенных случаях может не сработать никогда).

Единственный надёжный способ работать с таймерами и таймаутами — использовать монотонное время:
use Time::HiRes qw( clock_gettime CLOCK_MONOTONIC );
$now = clock_gettime(CLOCK_MONOTONIC);

Поддержка CLOCK_MONOTONIC была добавлена в Time::HiRes (по моей инициативе :)) два года назад. И вот сегодня я снова, как и два года назад, поискал на CPAN модули с правильной реализацией таймеров и таймаутов… и нашёл только один. :(
Tags:
Hubs:
+9
Comments 22
Comments Comments 22

Articles