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;
- }
c++11实现异步定时器的更多相关文章
- boost库学习随记六:使用同步定时器、异步定时器、bind、成员函数回调处理、多线程的同步处理示例等
一.使用同步定时器 这个示例程序通过展示如何在一个定时器执行一个阻塞等待. //makefile #-------------------------------------------------- ...
- 2018.2.11 JS的定时器制作
定时器 1.定时器定义 var time = window.setInterval("执行名词",间隔时间) 关闭定时器 clearInterval(定时器名称) 倒计时定时器 s ...
- 使用boost的deadline_timer实现一个异步定时器
概述 最近在工作上需要用到定时器,然后看到boost里面的deadline_timer可以实现一个定时器,所以就直接将其封装成了ATimer类,方便使用,ATimer有以下优点: 可以支持纳秒.毫秒. ...
- C++11 使用异步编程std::async和std::future
先说明一点:std::asyanc是std::future的高级封装, 一般我们不会直接使用std::futrue,而是使用对std::future的高级封装std::async. 下面分别说一下. ...
- 2015.3.11 VS异步控件及进度条结合应用
1.在Form中添加 指针控件:BackgroundWorker-bgwork:进度条控件progressBar1 以及开始.取消按钮 2.开始按钮启动异步线程 private void button ...
- 11 Windows编程——定时器
周期性的发送WWL_TIMER消息的一个东西,这个周期可以由程序员自己设定.设定周期的数是SetTimer,停止定时器消息发送的函数是:Killximer: 定时器消息的特点: 1.不准确(也就是说, ...
- 2020.11.2 异步IO 协程
异步IO 同步IO在一个线程中,CPU执行代码的速度极快,然而,一旦遇到IO操作,如读写文件.发送网络数据时,就需要等待IO操作完成,才能继续进行下一步操作. 在IO操作的过程中,当前线程被挂起,而其 ...
- 第11章 Windows线程池(1)_传统的Windows线程池
第11章 Windows线程池 11.1 传统的Windows线程池及API (1)线程池中的几种底层线程 ①可变数量的长任务线程:WT_EXECUTELONGFUNCTION ②Timer线程:调用 ...
- CoreAnimation6-基于定时器的动画和性能调优
基于定时器的动画 定时帧 动画看起来是用来显示一段连续的运动过程,但实际上当在固定位置上展示像素的时候并不能做到这一点.一般来说这种显示都无法做到连续的移动,能做的仅仅是足够快地展示一系列静态图片,只 ...
随机推荐
- 【C#/WPF】.Net生成二维码QRCode的工具
先马 http://qrcodenet.codeplex.com/ 使用该工具WPF生成二维码的简单例子: 前台XAML准备一个Image控件显示二维码. string qrcodeStr = &qu ...
- Java应用程序项目的打包与发行
Java应用程序项目的打包与发行 这里主要是讲解一下怎样将 Java程序打包成独立运行的exe程序包,以下这种方法应该是最佳的解决方案了.NetDuke的EXE 程序包了是使用这种方案制作的.在 ...
- CAS (2) —— Mac下配置CAS到Tomcat(客户端)
CAS (2) -- Mac下配置CAS到Tomcat(客户端) tomcat版本: tomcat-8.0.29 jdk版本: jdk1.8.0_65 cas版本: cas4.1.2 cas-clie ...
- KafkaStream时间戳问题CreateTime = -1引起的程序中断
Exception in thread "app-8835188a-e0a0-46da-ac2a-6820ec197628-StreamThread-1" org.apache.k ...
- JavaScriptSerializer 时间格式化
时间格式化 Model m = , Dt = DateTime.Now }; JavaScriptSerializer js = new JavaScriptSerializer(); string ...
- 【C】——压缩字符串
编一个函数,输入一个字符串,要求做一个新字符串,把其中所有的一个或多个连续的空白字符都压缩为一个空格.这里所说的空白包括空格.'\t'.'\n'.'\r'.例如原来的字符串是: This Conten ...
- l2正则化
在机器学习中,无论是分类还是回归,都可能存在由于特征过多而导致的过拟合问题.当然解决的办法有 (1)减少特征,留取最重要的特征. (2)惩罚不重要的特征的权重. 但是通常情况下,我们不知道应该惩罚哪些 ...
- jquery 自动完成 Autocomplete插件汇总
1. jQuery Autocomplete Mod jQuery Autcomplete插件.能够限制下拉菜单显示的结果数. 主页:http://www.pengoworks.com/worksho ...
- 消息中间件系列之Java API操作ActiveMQ
一.依赖 <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activem ...
- 关于Struts2的action的execute方法
这个方法必须要有一个String类型的返回值,所以如果写很多if else的话,记得要在最后加一个else,就是无论如何就会放回一个字符串,否则编译会报错,在execute方法名字下面有红线.