Вышла обновленная версия библиотеки timertt для работы с таймерами в C++ -- 1.1.2. В этой версии добавлена одна малюсенькая, но очень важная деталь: теперь в классах таймерных нитей и таймерных менеджеров есть публичное имя thread_safety. С его помощью стало гораздо проще писать шаблонный код, который может работать с разными типами таймерных нитей/менеджеров. Например:
// Класс для управления таймерами в прикладной программе. // Может работать с разными типами таймерных нитей или менеджеров. template< typename TIMER_CONTROLLER > class timer_client { TIMER_CONTROLLER & controller_; public : // Определяем тип идентификатора с учетом того, какой thread_safety // используется у менеджера таймеров. using timer_holder = timertt::timer_holder_object< typename TIMER_CONTROLLER::thread_safety >; // Создать новый таймер, при срабатывании которого нужно что-то выполнить. template< typename DURATION, typename ACT > auto schedule_action( DURATION timeout, ACT && action ) { timer_holder id = controller_.allocate(); controller_.activate( id, timeout, [act = std::move(action)] { act(); } ); return id; } // Отменить действие, которое было запланировано. void cancel_action( timer_holder id ) { controller_.deactivate( id ); } ... }; using mtsafe_wheel_manager = timertt::timer_wheel_manager< timertt::thread_safety::safe >; timer_client< mtsafe_wheel_manager > client1(...); auto id1 = client1.schedule_action( 250ms, []{ ... } ); ... client1.cancel_action( id1 ); using mtunsafe_wheel_manager = timertt::timer_wheel_manager< timertt::thread_safety::unsafe >; timer_client< mtunsafe_wheel_manager > client2(...); auto id2 = client2.schedule_action( 500ms, []{ ... } ); ... client2.cancel_action( id2 ); |
Без этого маленького дополнения класс timer_client пришлось бы делать зависящим от двух параметров шаблонов: от самого таймерного механизма и от признака thread_safety. Начиная с версии 1.1.2 достаточно всего одного шаблонного параметра.
Если вдруг кто-то не в курсе, что такое timertt, то в нескольких словах это:
Header-only библиотека без внешних зависимостей, базирующаяся на возможностях стандартной библиотеки C++11. Реализует таймеры на основе тайм-аутов, т.е. таймеры, которые должны сработать через сколько-то миллисекунд (секунд, минут и т.д.) после момента активации таймера. wallclock-таймеры не поддерживаются.
Таймеры могут быть однократными (срабатывают всего один раз, после чего деактивируются), либо периодическими (повторяются до тех пор, пока не будут явно деактивированы или пока таймерная нить не завершит свою работу).
Библиотека поддерживает три таймерных механизма: timer_wheel, timer_heap и timer_list, у каждого из которых есть свои преимущества и недостатки. Может поддерживаться большое количество таймеров (десятки и сотни миллионов) и обеспечивается высокая скорость обработки таймеров (до нескольких миллионов в секунду).
Кросс-платформенная, проверялась посредством MSVS2013, 2015, 2017 (Windows), GCC 4.9-6.3 (Windows, Linux), Clang 3.5-3.9 (Linux, FreeBSD).
Распространяется под 3-х секционной BSD-лицензией, может свободно использоваться как в открытых, так и в закрытых коммерческих проектах.
Мы сделали timertt где-то 2.5 года назад, с тех пор она верой и правдой служит нам в SObjectizer-е. Последние правки вносились почти два года назад, когда вышла версия 1.1.1. За все время каких-то проблем с timertt не замечено.
Библиотека разрабатывалась для замены ACE в проекте SObjectizer, поэтому все, что связано с timertt, находится на SourceForge:
- архивы с исходными текстами доступны в секции Files. Архив timertt-1.1.2-headeronly.7z содержит только основной заголовочный файл со всей функциональностью timertt. Архив timertt-1.1.2-full.7z содержит так же тесты, примеры и сгенерированный посредством Doxygen API Reference Manual;
- основная документация для проекта собрана в Wiki;
- исходники лежат в Subversion-репозитории на SourceForge. Релизные версии в tags/timertt, находящиеся в разработке версии в branches/timertt.