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

}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值