zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    10个强大的Apache开源模块
    Flume日志收集(转载)
    hbase安装配置(整合到hadoop)
    Hadoop与HBase兼容版本汇总
    关于Mysql Proxy LUA实现Mysql读写分离
    Redis发布了集群版3.0.0 beta
    Spring MVC 学习之 400 错误
    Mahout安装(Hadoop 1.2.1 版本)
    【Android】性能优化
    【Android】asynchronous http client
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4924097.html
Copyright © 2011-2022 走看看