c++11实现异步定时器

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

#include

#include

#include

#include

#include

#include

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<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 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;

            }

        }

    }

     

    templateclass... arguments>

    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();

    }

    templateclass... arguments>

    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

#include

#include

#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;

}

你可能感兴趣的:(c++11实现异步定时器)