博客转载自: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. python 百题计划

    一.基础篇 想要像类似执行shell脚本一样执行Python脚本,需要在py文件开头加上什么?KEY:#!/usr/bin/env python Python解释器在加载 .py 文件中的代码时,会对 ...

  2. 455. Assign Cookies Add to List

    Assume you are an awesome parent and want to give your children some cookies. But, you should give e ...

  3. .net core结合Consul集群&Docker实现服务治理

    实战中的asp.net core结合Consul集群&Docker实现服务治理 https://www.cnblogs.com/guolianyu/p/9614050.html 0.目录 整体 ...

  4. HIVE-利用ow_number() OVER(PARTITION BY)函数介绍求TOP-K

    http://blog.csdn.net/631799/article/details/7419797 第一句话: select row_number() over (partition by mon ...

  5. bzoj 1977 [BeiJing2010组队]次小生成树 Tree

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1977 kruscal别忘了先按边权sort.自己觉得那部分处理得还挺好的.(联想到之前某题的 ...

  6. Process使用

    最近在一个项目中,需要在C#中调用cmd窗口来执行一个命令,使用到了Process这个类,使用过程中遇到不少问题,好在终于解决了.赶紧记录下来. Process process = new Proce ...

  7. Python:函数变量的使用

    1.上层函数不能直接使用其嵌套函数的变量: def func1(x, y): z = x + y def func2(): m = 3 z += m return z print(func1(1, 2 ...

  8. spring学习七

    一: web.xml中常用配置元素? <servlet></servlet>: 在向servlet或JSP页面制定初始化参数或定制URL时,首先命名servlet或JSP页面. ...

  9. 0ctf签到题

    签到题: 题目提示: flag在IRC聊天室里 开启weechat ┌─[root@sch01ar]─[~] └──╼ #weechat 创建服务器 /server add freenode8001 ...

  10. RPC: program not registered (ZT)

    When we trying to use a particular RPC  program, below may indicate that rpcbind is not running or t ...