博客转载自:http://blog.csdn.net/liujiayu2/article/details/50384537

同步Timer

asio中提供的timer名为deadline_timer,它提供了超时计时的功能。首先以一个最简单的同步Timer为例来演示如何使用它。

  1. #include <iostream>
  2. #include <boost/asio.hpp>
  3.  
  4. int main()
  5. {
  6. boost::asio::io_service io;
  7. boost::asio::deadline_timer timer(io, boost::posix_time::seconds());
  8.  
  9. timer.wait();
  10. std::cout << "Hello, world!\n";
  11. return ;
  12. }

首先常见了一个io_service对象,它提供了IO调度功能,asio库中的所有io操作都是基于它来执行的。然后创建了一个deadline_timer对象,它有两个参数,一个是io_service对象,另一个是超时时间。

创建了timer后,就可以调用wait函数来阻塞等待至timer超时了,它还有一种可以指定错误码的入参的重载形式,关于错误码后面再介绍。

异步Timer

同步timer虽然简单,但由于其会阻塞,在实际的项目中并不常用,而往往使用的是异步timer:指定一个回调函数,计时器超时后执行回调函数。asio中实现异步timer比较简单,示例如下:

  1. void print(const boost::system::error_code& /*e*/)
  2. {
  3. std::cout << "Hello, world!\n";
  4. }
  5.  
  6. int main()
  7. {
  8. boost::asio::io_service io;
  9. boost::asio::deadline_timer timer(io, boost::posix_time::seconds());
  10.  
  11. timer.async_wait(&print);
  12. io.run();
  13.  
  14. return ;
  15. }

和同步方式相比,它主要有两点不同:

  1. 调用的是非阻塞函数async_wait,它的入参是一个回调函数。
  2. 显式调用io_service.run()函数驱动异步IO调度。

取消Timer

  1. void print(const boost::system::error_code& err)
  2. {
  3. if(err)
  4. {
  5. std::cout << "timer is canceled\n";
  6. return;
  7. }
  8.  
  9. std::cout << "Hello, world!\n";
  10. }
  11.  
  12. int main()
  13. {
  14. boost::asio::io_service io;
  15.  
  16. boost::asio::deadline_timer timer(io, boost::posix_time::seconds());
  17. timer.async_wait(&print);
  18.  
  19. boost::asio::deadline_timer timer2(io, boost::posix_time::seconds());
  20. timer2.wait();
  21. timer.cancel();
  22.  
  23. io.run();
  24. return ;
  25. }

更改Timer超时时间

可以通过expires_from_now和expires_at两个函数更改Timer的超时时间,如下示例就通过它实现一个周期计时器。

Timer还有一种常用操作是取消Timer,基本方法如下:

  1. 调用timer的cancel函数取消timer
  2. timer取消后,回调函数会立即执行,通过err_code可以感知到计时器是否已经被取消
  1. typedef std::function<void (const boost::system::error_code&)> timer_callback ;
  2. void print(const boost::system::error_code&)
  3. {
  4. std::cout << "Hello, world!\n";
  5. }
  6.  
  7. int main()
  8. {
  9. boost::asio::io_service io;
  10. boost::asio::deadline_timer timer(io, boost::posix_time::seconds());
  11.  
  12. timer_callback callback = [&](const boost::system::error_code& err)
  13. {
  14. print(err);
  15. timer.expires_at(timer.expires_at() + boost::posix_time::seconds());
  16. timer.async_wait(callback);
  17. };
  18.  
  19. timer.async_wait(callback);
  20. io.run();
  21. return ;
  22. }

//

  1. #include <iostream>
  2. #include <boost/asio.hpp>
  3. #include <boost/bind.hpp>
  4. #include <boost/date_time/posix_time/posix_time.hpp>
  5.  
  6. class printer
  7. {
  8. public:
  9. printer(boost::asio::io_service& io)
  10. : timer_(io, boost::posix_time::seconds()),
  11. count_()
  12. {
  13. timer_.async_wait(boost::bind(&printer::print, this));
  14. }
  15.  
  16. ~printer()
  17. {
  18. std::cout << "Final count is " << count_ << "\n";
  19. }
  20.  
  21. void print()
  22. {
  23. if (count_ < )
  24. {
  25. std::cout << count_ << "\n";
  26. ++count_;
  27.  
  28. timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds());
  29. timer_.async_wait(boost::bind(&printer::print, this));
  30. }
  31. }
  32.  
  33. private:
  34. boost::asio::deadline_timer timer_;
  35. int count_;
  36. };
  37.  
  38. int main()
  39. {
  40. boost::asio::io_service io;
  41. printer p(io);
  42. io.run();
  43.  
  44. return ;
  45. }

//

  1. #include <iostream>
  2. #include <time.h>
  3. #include <boost/asio.hpp>
  4. #include <boost/bind.hpp>
  5. #include <boost/function.hpp>
  6. #include <boost/date_time/posix_time/posix_time.hpp>
  7.  
  8. using namespace std;
  9.  
  10. //超时控制器类
  11. class TimerController
  12. {
  13. public:
  14.  
  15. /**
  16. * 超时控制器构造函数
  17. * @param ios 异步I/O对象
  18. * @param callbackFunc 超时处理回调函数
  19. * @param uiWaitSec 定时器间隔等待时间,单位:秒
  20. */
  21. explicit TimerController(boost::asio::io_service &ios, boost::function<void()> callbackFunc, unsigned int uiWaitSec) :
  22. m_timer(ios, boost::posix_time::seconds())
  23. {
  24. cout<< "" << "-----" << time(NULL)<<endl;
  25. m_timeoutHandle = callbackFunc;
  26. m_uiWaitSec = uiWaitSec;
  27. m_timer.async_wait(boost::bind(&TimerController::onTime, this, boost::asio::placeholders::error));
  28. }
  29.  
  30. /**
  31. * 析构函数
  32. */
  33. ~TimerController()
  34. {
  35. m_timer.cancel();
  36. }
  37.  
  38. /**
  39. * 定时器响应函数
  40. * @param error_code 定时器异常错误信息
  41. */
  42. void onTime(const boost::system::error_code&)
  43. {
  44. m_timeoutHandle();
  45. m_timer.expires_at(m_timer.expires_at() + boost::posix_time::seconds());
  46. m_timer.async_wait(boost::bind(&TimerController::onTime, this, boost::asio::placeholders::error));
  47. }
  48.  
  49. private:
  50. unsigned int m_uiWaitSec; //定时间间隔等待时间
  51. boost::asio::deadline_timer m_timer; //asio定时器
  52. boost::function<void()> m_timeoutHandle; //超时处理回调函数
  53. };
  54.  
  55. //构造函数
  56. class CmdQueueManager
  57. {
  58. public:
  59. CmdQueueManager(boost::asio::io_service* io)
  60. {
  61. m_pTimer = new TimerController(*io,boost::bind(&CmdQueueManager::SendProcess, this),);
  62. }
  63.  
  64. void SendProcess()
  65. {
  66. cout<< "" << "-----" << time(NULL)<<endl;
  67. }
  68.  
  69. TimerController * m_pTimer;
  70. };
  71.  
  72. int main()
  73. {
  74. boost::asio::io_service io;
  75.  
  76. CmdQueueManager t(&io);
  77. io.run();
  78.  
  79. return ;
  80. }

最近做项目时,做了一个定时器,发现定时器回调函数不按照指定时间回调,总是延迟,后经研究发现,是IO出了问题,把一个IO绑定到多个socket上面,并把这个IO绑定到定时器上面,有一些socket连接网络时发出了一些connect行为,这些行为会造成IO阻塞,当然这只是猜测,看到的读者可以帮忙讲解一下。所以本人建议做timer时候,自建一个人“干净”的IO。

【Boost】boost库中timer定时器 1的更多相关文章

  1. 【Boost】boost库中timer定时器 2

    博客转载自:http://blog.csdn.net/yockie/article/details/40386145 先跟着boost文档中asio章节的指南中的几个例子学习一下使用: 所有的Asio ...

  2. 浅析linux内核中timer定时器的生成和sofirq软中断调用流程(转自http://blog.chinaunix.net/uid-20564848-id-73480.html)

    浅析linux内核中timer定时器的生成和sofirq软中断调用流程 mod_timer添加的定时器timer在内核的软中断中发生调用,__run_timers会spin_lock_irq(& ...

  3. 浅析linux内核中timer定时器的生成和sofirq软中断调用流程【转】

    转自:http://blog.chinaunix.net/uid-20564848-id-73480.html 浅析linux内核中timer定时器的生成和sofirq软中断调用流程 mod_time ...

  4. asp.net中Timer定时器在web中无刷新的使用

    最近在做一个项目的时候,web端的数据需要与数据源进行实时同步,并保证数据的准确性,当时,考虑到使用ajax异步刷新技术.但后来在网上查找相关资料时,发现这样做,太浪费资源了,因为ajax的提交请求不 ...

  5. C#中Timer定时器的使用示例

    关于C#中timer类 在C#里关于定时器类就有3个: 1.定义在System.Windows.Forms里 2.定义在System.Threading.Timer类里 3.定义在System.Tim ...

  6. .net中 Timer定时器

    作者:feiying008 在开发一套视觉系统时,发现系统内存一直不断增加,直至系统内存爆满.一开始还以为是程序内存泄露,是图像操作算法写的有问题,但是,发现如果电机轴如果 不运行的状态下,每隔一秒进 ...

  7. 关于C#中Timer定时器的重入问题解决方法(也适用于多线程)

    项目中用到了定时器随着服务启动作定时任务,按指定的准点时间定时执行相关操作,但是在指定准点时间内我只想让它执行一次,要避免重入问题的发生. 首先简单介绍一下timer,这里所说的timer是指的Sys ...

  8. Boost C++ 库 中文教程(全)

    Boost C++ 库 目录 第 1 章 简介 第 2 章 智能指针 第 3 章 函数对象 第 4 章 事件处理 第 5 章 字符串处理 第 6 章 多线程 第 7 章 异步输入输出 第 8 章 进程 ...

  9. 使用Boost库中的组件进行C++内存管理

    C++标准库中的auto_ptr,智能指针,部分的解决了获取资源自动释放的问题 在Boost中,提供了6中智能指针:scoped_ptr, scoped_array, shared_ptr, shar ...

随机推荐

  1. Java 模拟ATM(修正)

    ATM机的账户记录Account有账户的唯一性标识(11个长度的字符和数字的组合),用户的姓名,操作日期(Date),操作类型,账户密码(六位的数字,可以用0开头),当前的余额(可以为0). 模拟AT ...

  2. app-前端性能测试

    前端性能测试,主要分为七个部分: 启动时间.CPU.流量.电量.内存.FPS(每秒钟的帧数).过度渲染 主要测试的内容: 启动时间:主要测试app在启动过程中的耗时情况 CPU:主要测试app在使用过 ...

  3. LeetCode OJ:Rotate Array(倒置数组)

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array  ...

  4. UVA - 1608 Non-boring sequences (分治,中途相遇法)

    如果一个序列中是否存在一段连续子序列中的每个元素在该子序列中都出现了至少两次,那么这个序列是无聊的,反正则不无聊.给你一个长度为n(n<=200000)的序列,判断这个序列是否无聊. 稀里糊涂A ...

  5. volatile关键字及内存可见性

    先看一段代码: package com.java.juc; public class TestVolatile { public static void main(String[] args) { T ...

  6. C++中rand()函数的用法

    1.rand()不需要参数,它会返回一个从0到最大随机数的任意整数,最大随机数的大小通常是固定的一个大整数. 2.如果你要产生0~99这100个整数中的一个随机整数,可以表达为:int num = r ...

  7. 前端用户输入校验--基于JQ

    <!DOCTYPE html> <html> <head> <title>用户输入校验</title> </head> < ...

  8. Oracl使用总结二

    1.ORA-00972: 标识符过长 错误排除 可能原因: 1.如果是拼接成的sql语句,请查找传递参数时字符型字段是否两边少了引号.2.数据库表名太长了,附各种类型的数据库表名长度: SQLSERV ...

  9. 四、Jmeter--参数化

    一.CSV 参数化 1.我们做性能测试需要并发多个用户,为了真实模拟用户行为,我们需要模拟多个不同的用户登录,这是我们就需要进行参数化.这里我们选择比较常用的参数化方法-CSV Data Set Co ...

  10. Visualforce Page CSS样式

    Salesforce Page开发者文档:https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_stylin ...