基于c++11设计一个定时器timer
来源:互联网 发布:家庭网限制80端口吗 编辑:程序博客网 时间:2024/06/09 21:35
这里设计了一个异步定时器,在windows下定时器通常是基于消息队列实现的,也是同步的。c++11提供了一系列方便我写一个跨平台定时器的标准函数和类。以下是一个简单的但是完备的定时器的实现。
#pragma once#include <limits>#include <condition_variable> // std::condition_variable#include <chrono>#include <thread>#include <mutex>#include <memory>#include <functional>#include <atomic>#include "min_max_heap.hpp"//仿照消息队列queue,添加了几个函数,他是最小堆。代码就不上传了#if defined(_WIN32)#define TRACE(...) _CrtDbgReport( _CRT_WARN, __FILE__, __LINE__, "min_max_heap",__VA_ARGS__ );#else#define TRACE(...) printf(__VA_ARGS__);#endifnamespace prudens{ uint64_t now() { return duration_cast<milliseconds>( system_clock::now() - time_point<system_clock>() ).count(); } typedef std::function<void( uint32_t, void* ) > timer_callback; struct timer_msg {#define MAX_MACRO_COMPILE_SUPPORT uint32_t timer_id; uint32_t elapsed; uint64_t expired; bool repeat; void* userdata; timer_callback action; timer_msg() :timer_id( 0 ), elapsed( 0 ), expired( std::numeric_limits<uint64_t>::max MAX_MACRO_COMPILE_SUPPORT() ), repeat( false ), userdata( nullptr ) {} bool operator < ( const timer_msg& other )const { return this->elapsed < other.elapsed; } }; class timer { public: class TimerQueue { public: TimerQueue() { _stop.store( false ); _flag.store( false ); } void run() { while ( true ) { while ( true ) { if (_stop) { return; } timer_msg msg; uint64_t t = now(); { std::lock_guard<std::mutex> guard( _mutex ); if ( !_timers.empty() ) { msg = _timers.top(); } } if ( msg.expired >= t ) { break; } if ( msg.action ) { msg.action( msg.timer_id, msg.userdata ); } { std::lock_guard<std::mutex> guard( _mutex ); if ( !_timers.empty() ) { _timers.pop(); if ( msg.repeat ) { msg.expired = msg.elapsed + now(); _timers.push( msg ); } } } } int32_t sleep_time = std::numeric_limits<int32_t>::max MAX_MACRO_COMPILE_SUPPORT ();//列表为空的时候就睡眠30ms { std::lock_guard<std::mutex> guard( _mutex ); if ( !_timers.empty() ) { sleep_time = static_cast<int32_t>(_timers.top().expired - now()); if (sleep_time<0) { continue; } } } if (_stop) { return; } std::unique_lock <std::mutex> lck( _mutex ); if ( _flag.load() == false ) { if ( _cv.wait_for( lck, milliseconds( sleep_time ), [this] ()->bool { return this->_flag.load(); } ) ) { TRACE( "cv is time out:%d\n", sleep_time ); } else { TRACE( "cv flag is true\n" ); } } _flag.store( false ); } } void push( timer_msg& msg ) { std::unique_lock <std::mutex> lck( _mutex ); _timers.push( msg ); _flag.store( true ); _cv.notify_all(); } void clear() { std::lock_guard<std::mutex> guard( _mutex ); while ( !_timers.empty() ) { _timers.pop(); } } void remove( uint32_t time_id ) { std::lock_guard<std::mutex> guard( _mutex ); _timers.remove_if( [&] ( const timer_msg& msg ) { return msg.timer_id == time_id; } ); } private: std::atomic_bool _stop; prudens::max_min_heap<timer_msg> _timers; std::mutex _mutex; std::condition_variable _cv; std::atomic_bool _flag; }; timer() { _queue = std::make_shared<TimerQueue>(); std::thread( [] ( std::shared_ptr<TimerQueue> queue ) { queue->run(); },_queue ).detach(); } ~timer() { _queue->clear(); } uint32_t start( int elapsed_ms, bool repeat, timer_callback action,void* userdata ) { timer_msg msg; msg.elapsed = elapsed_ms ; msg.expired = elapsed_ms + now(); msg.repeat = repeat; msg.userdata = userdata; msg.timer_id = s_timer_id++; msg.action = action; _queue->push( msg ); return msg.timer_id; } void remove( uint32_t time_id ) { _queue->remove( time_id ); } private: std::shared_ptr<TimerQueue> _queue; static uint32_t s_timer_id; }; uint32_t timer::s_timer_id = 1;}
0 0
- 基于c++11设计一个定时器timer
- 一个定时器Timer类
- Timer定时器(C++)
- 基于时间段的Timer定时器执行任务
- C#--利用Timer控件设计一个电子时钟。
- No.1 定时器接口timer的设计
- 定时器(Timer)的一个小列子
- 自己写的一个定时器 timer
- Timer 定时器
- TIMER 定时器
- timer 定时器
- timer 定时器
- timer定时器
- 定时器 Timer
- 定时器Timer
- timer定时器
- Timer 定时器
- Timer定时器
- 线性布局上的一个小错误
- 动态规划(dynamic programming)初步入门
- android UI进阶之实现listview的分页加载
- Oracle 的自治事务 AUTONOMOUS TRANSACTION
- Robot Framework 自动化测试框架安装
- 基于c++11设计一个定时器timer
- PCM data flow - part 2: ASoC data structure
- android中的内外部存储
- 防止js注入
- opencv目标跟踪:二帧差法(批量读取视频帧)
- 47. Permutations II
- 查看UNIX/Linux资源占用的top命令
- ListView分页加载数据
- Python库在Windows机子的整体平移的尝试