网站搬家数据库配置,天天外链官网,宣城公司做网站,网站建站案例定时器要求在固定的时间异步执行一个操作#xff0c;比如boost库中的boost::asio::deadline_timer#xff0c;以及MFC中的定时器。也可以利用c11的thread, mutex, condition_variable 来实现一个定时器。
1、使用C11中的thread, mutex, condition_variable来实现一个定时器。…定时器要求在固定的时间异步执行一个操作比如boost库中的boost::asio::deadline_timer以及MFC中的定时器。也可以利用c11的thread, mutex, condition_variable 来实现一个定时器。
1、使用C11中的thread, mutex, condition_variable来实现一个定时器。 注此算法会每一个任务创建一个线程不推荐。推荐用最下面第2种时间轮算法
#include iostream
#include chrono
#include thread
#include mutex
#include condition_variableclass Timer {
public:Timer() :_expired(true), _try_to_expire(false) {}Timer(const Timer t) {_expired t._expired.load();_try_to_expire t._try_to_expire.load();}~Timer() {Expire();}void StartTimer(int interval, std::functionvoid() task) {if (_expired false) {return;}_expired false;std::thread([this, interval, task]() {while (!_try_to_expire) {std::this_thread::sleep_for(std::chrono::milliseconds(interval));task();}{std::lock_guardstd::mutex locker(_mutex);_expired true;_expired_cond.notify_one();}}).detach();}void Expire() {if (_expired) {return;}if (_try_to_expire) {return;}_try_to_expire true;{std::unique_lockstd::mutex locker(_mutex);_expired_cond.wait(locker, [this] {return _expired true; });if (_expired true) {_try_to_expire false;}}}private:std::atomicbool _expired;std::atomicbool _try_to_expire;std::mutex _mutex;std::condition_variable _expired_cond;
};int main() {Timer t;t.StartTimer(1000, []() {std::cout Hello World! std::endl; });std::this_thread::sleep_for(std::chrono::seconds(4));t.Expire();return 0;
}2、使用时间轮算法Linux内核就有这个算法。这里也有一个用户态的实现供参考github.com/facebook/folly。它的高精度版本能实现微妙级别的定时。下面是一个简单的时间轮定时器的C实现。原文的代码有问题不能循环定时经修改已经支持 #include chrono
#include functional
#include list
#include mutex
#include thread
#include vectorclass TimerWheel {
public:using Task std::functionvoid();explicit TimerWheel(size_t wheel_size, int interval_ms): wheel_size_(wheel_size),interval_ms_(interval_ms),wheel_(wheel_size),current_index_(0) {}~TimerWheel() {Stop();}void Start() {if (running_) {return;}running_ true;thread_ std::thread([this]() {while (running_) {std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms_));Tick();}std::cout timer oooops! std::endl;});thread_.detach();}void Stop() {if (!running_) {return;}running_ false;if (thread_.joinable()) {thread_.join();}}void AddTask(int timeout_ms, Task task) {std::lock_guardstd::mutex lock(mutex_);size_t ticks timeout_ms / interval_ms_;size_t index (current_index_ ticks) % wheel_size_;size_t allindex index;for (size_t i 1 ; allindex wheel_size_; i){allindex index * i;if (allindex wheel_size_)break;wheel_[allindex].push_back(task);}}private:void Tick() {std::lock_guardstd::mutex lock(mutex_);auto tasks wheel_[current_index_];for (const auto task : tasks) {task();}//tasks.clear();current_index_ (current_index_ 1) % wheel_size_;}private:size_t wheel_size_;int interval_ms_;std::vectorstd::listTask wheel_;size_t current_index_;bool running_ false;std::thread thread_;std::mutex mutex_;
};
使用方法 使用static声明以免被析构可在cpp类外全局声明第一个参数为任务容器最大数量第二个参数为定时判断的毫秒数即最低检测时间单位
static TimerWheel timer(10, 1000);在要使用的地方启动并添加任务
timer.Start();
timer.AddTask(2000, []() {std::cout Task 1 std::endl; });
timer.AddTask(3000, []() {std::cout Task 2 std::endl; });可以在需要的时候停止
timer.Stop();原文链接https://blog.csdn.net/sinat_28305511/article/details/131495316