博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++11实现异步定时器
阅读量:6992 次
发布时间:2019-06-27

本文共 3400 字,大约阅读时间需要 11 分钟。

hot3.png

c++11提供了丰富的时间和线程操作函数,比如 std::this_thread::sleep, std::chrono::seconds等。可以利用这些来很方便的实现一个定时器。 定时器要求在固定的时间异步执行一个操作,比如boost库中的boost::asio::deadline_timer,以及MFC中的定时器。这里,利用c++11的thread, mutex, condition_variable 来实现一个定时器: 定时器要求异步执行任务 ----> 开辟独立的线程 定时器要求能够启动和取消 ----> 提供安全的取消操作,使用互斥量和信号量 定时器要求每个定时时刻到达的时候执行的任务要尽可能节省时间 实现

#ifndef TIMER_H_ #define TIMER_H_ #include<functional> #include<chrono> #include<thread> #include<atomic> #include<memory> #include<mutex> #include<condition_variable> class 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();    //      std::cout << "timer destructed!" << std::endl;}void StartTimer(int interval, std::function
task){ if (expired_ == false){ // std::cout << "timer is currently running, please expire it first..." << std::endl; return; } expired_ = false; std::thread([this, interval, task](){ while (!try_to_expire_){ std::this_thread::sleep_for(std::chrono::milliseconds(interval)); task(); } // std::cout << "stop task..." << std::endl; { std::lock_guard
locker(mutex_); expired_ = true; expired_cond_.notify_one(); } }).detach();}void Expire(){ if (expired_){ return; } if (try_to_expire_){ // std::cout << "timer is trying to expire, please wait..." << std::endl; return; } try_to_expire_ = true; { std::unique_lock
locker(mutex_); expired_cond_.wait(locker, [this]{return expired_ == true; }); if (expired_ == true){ // std::cout << "timer expired!" << std::endl; try_to_expire_ = false; } }} template
void SyncWait(int after, callable&& f, arguments&&... args){ std::function
::type()> task (std::bind(std::forward
(f), std::forward
(args)...)); std::this_thread::sleep_for(std::chrono::milliseconds(after)); task();}template
void AsyncWait(int after, callable&& f, arguments&&... args){ std::function
::type()> task (std::bind(std::forward
(f), std::forward
(args)...)); std::thread([after, task](){ std::this_thread::sleep_for(std::chrono::milliseconds(after)); task(); }).detach();}

private: std::atomic<bool> expired_; std::atomic<bool> try_to_expire_; std::mutex mutex_; std::condition_variable expired_cond_; }; #endif

test.cpp #include<iostream> #include<string> #include<memory> #include"Timer.hpp" using namespace std; void EchoFunc(std::string&& s){ std::cout << "test : " << s << endl; }

int main(){ Timer t; //周期性执行定时任务 t.StartTimer(1000, std::bind(EchoFunc,"hello world!")); std::this_thread::sleep_for(std::chrono::seconds(4)); std::cout << "try to expire timer!" << std::endl; t.Expire();

//周期性执行定时任务t.StartTimer(1000, std::bind(EchoFunc,  "hello c++11!"));std::this_thread::sleep_for(std::chrono::seconds(4));std::cout << "try to expire timer!" << std::endl;t.Expire();std::this_thread::sleep_for(std::chrono::seconds(2));//只执行一次定时任务//同步t.SyncWait(1000, EchoFunc, "hello world!");//异步t.AsyncWait(1000, EchoFunc, "hello c++11!");std::this_thread::sleep_for(std::chrono::seconds(2));return 0;

}

转载于:https://my.oschina.net/u/1426828/blog/1817272

你可能感兴趣的文章