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

同步Timer

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

 #include <iostream>
#include <boost/asio.hpp> int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds()); timer.wait();
std::cout << "Hello, world!\n";
return ;
}

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

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

异步Timer

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

void print(const boost::system::error_code& /*e*/)
{
std::cout << "Hello, world!\n";
} int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer timer(io, boost::posix_time::seconds()); timer.async_wait(&print);
io.run(); return ;
}

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

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

取消Timer

void print(const boost::system::error_code& err)
{
if(err)
{
std::cout << "timer is canceled\n";
return;
} std::cout << "Hello, world!\n";
} int main()
{
boost::asio::io_service io; boost::asio::deadline_timer timer(io, boost::posix_time::seconds());
timer.async_wait(&print); boost::asio::deadline_timer timer2(io, boost::posix_time::seconds());
timer2.wait();
timer.cancel(); io.run();
return ;
}

更改Timer超时时间

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

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

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

//

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> class printer
{
public:
printer(boost::asio::io_service& io)
: timer_(io, boost::posix_time::seconds()),
count_()
{
timer_.async_wait(boost::bind(&printer::print, this));
} ~printer()
{
std::cout << "Final count is " << count_ << "\n";
} void print()
{
if (count_ < )
{
std::cout << count_ << "\n";
++count_; timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds());
timer_.async_wait(boost::bind(&printer::print, this));
}
} private:
boost::asio::deadline_timer timer_;
int count_;
}; int main()
{
boost::asio::io_service io;
printer p(io);
io.run(); return ;
}

//

#include <iostream>
#include <time.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> using namespace std; //超时控制器类
class TimerController
{
public: /**
* 超时控制器构造函数
* @param ios 异步I/O对象
* @param callbackFunc 超时处理回调函数
* @param uiWaitSec 定时器间隔等待时间,单位:秒
*/
explicit TimerController(boost::asio::io_service &ios, boost::function<void()> callbackFunc, unsigned int uiWaitSec) :
m_timer(ios, boost::posix_time::seconds())
{
cout<< "" << "-----" << time(NULL)<<endl;
m_timeoutHandle = callbackFunc;
m_uiWaitSec = uiWaitSec;
m_timer.async_wait(boost::bind(&TimerController::onTime, this, boost::asio::placeholders::error));
} /**
* 析构函数
*/
~TimerController()
{
m_timer.cancel();
} /**
* 定时器响应函数
* @param error_code 定时器异常错误信息
*/
void onTime(const boost::system::error_code&)
{
m_timeoutHandle();
m_timer.expires_at(m_timer.expires_at() + boost::posix_time::seconds());
m_timer.async_wait(boost::bind(&TimerController::onTime, this, boost::asio::placeholders::error));
} private:
unsigned int m_uiWaitSec; //定时间间隔等待时间
boost::asio::deadline_timer m_timer; //asio定时器
boost::function<void()> m_timeoutHandle; //超时处理回调函数
}; //构造函数
class CmdQueueManager
{
public:
CmdQueueManager(boost::asio::io_service* io)
{
m_pTimer = new TimerController(*io,boost::bind(&CmdQueueManager::SendProcess, this),);
} void SendProcess()
{
cout<< "" << "-----" << time(NULL)<<endl;
} TimerController * m_pTimer;
}; int main()
{
boost::asio::io_service io; CmdQueueManager t(&io);
io.run(); return ;
}

最近做项目时,做了一个定时器,发现定时器回调函数不按照指定时间回调,总是延迟,后经研究发现,是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. UVA - 1632 Alibaba (区间dp+常数优化)

    题目链接 设$dp[l][r][p]$为走完区间$[l,r]$,在端点$p$时所需的最短时间($p=0$代表在左端点,$p=1$代表在右端点) 根据题意显然有状态转移方程$\left\{\begin{ ...

  2. 数据处理之pandas库

    1. Series对象 由于series对象很简单,跟数组类似,但多了一些额外的功能,偷个懒,用思维导图表示 2. DaraFrame对象 DataFrame将Series的使用场景由一维扩展到多维, ...

  3. tableau学习笔记—1

    第一部分 第一章 数据可视化 1.1 用数据讲故事 1.2 数据不只是数字 1.3 在数据中寻找什么(关系.模式.异常) 第二章 Tableau概述 2.1 Tableau概述 2.2 产品简介 第三 ...

  4. LeetCode Distribute Candies

    原题链接在这里:https://leetcode.com/problems/distribute-candies/#/description 题目: Given an integer array wi ...

  5. GO语言heap剖析及利用heap实现优先级队列

    GO语言heap剖析 本节内容 heap使用 heap提供的方法 heap源码剖析 利用heap实现优先级队列 1. heap使用 在go语言的标准库container中,实现了三中数据类型:heap ...

  6. python的编解码问题

    http://blog.chinaunix.net/uid-27838438-id-4227131.html

  7. bzoj 4712 洪水——动态DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4712 因为作为动态DP练习而找到,所以就用动态DP做了,也没管那种二分的方法. 感觉理解似乎 ...

  8. touch: cannot touch '/usr/local/tomcat/logs/catalina.out': Permission denied解决方法

    一.报以下错误: ./startup.sh Using CATALINA_BASE: /usr/local/tomcat702 Using CATALINA_HOME: /usr/local/tomc ...

  9. Bug:DataGridCell的显示不完整

    最近在使用DataGrid时遇到一个bug, 在客户机器上DataGrid的内容显示不完整, 具体表现为某些列的显示为空. 具体的可视树为:DataGridCell > ContentPrese ...

  10. sleep(0)作用

    假设现在是 2008-4-7 12:00:00.000,如果我调用一下 Thread.Sleep(1000) ,在 2008-4-7 12:00:01.000 的时候,这个线程会 不会被唤醒?某人的代 ...