c++11實現異步定時器

c++11提供了豐富的時間和線程操做函數,好比 std::this_thread::sleep, std::chrono::seconds等。能夠利用這些來很方便的實現一個定時器。 定時器要求在固定的時間異步執行一個操做,好比boost庫中的boost::asio::deadline_timer,以及MFC中的定時器。這裏,利用c++11的thread, mutex, condition_variable 來實現一個定時器: 定時器要求異步執行任務 ----> 開闢獨立的線程 定時器要求可以啓動和取消 ----> 提供安全的取消操做,使用互斥量和信號量 定時器要求每一個定時時刻到達的時候執行的任務要儘量節省時間 實現ios

#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){ }c++

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<void()> 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<std::mutex> 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<std::mutex> locker(mutex_);
        expired_cond_.wait(locker, [this]{return expired_ == true; });
        if (expired_ == true){
            //              std::cout << "timer expired!" << std::endl;
            try_to_expire_ = false;
        }
    }
}
 
template<typename callable, class... arguments>
void SyncWait(int after, callable&& f, arguments&&... args){

    std::function<typename std::result_of<callable(arguments...)>::type()> task
        (std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));
    std::this_thread::sleep_for(std::chrono::milliseconds(after));
    task();
}
template<typename callable, class... arguments>
void AsyncWait(int after, callable&& f, arguments&&... args){
    std::function<typename std::result_of<callable(arguments...)>::type()> task
        (std::bind(std::forward<callable>(f), std::forward<arguments>(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;

}this

相關文章
相關標籤/搜索