boost::asio::deadline_timer(理解)

本文详细介绍了Boost.ASIO库中的`deadline_timer`,通过示例展示了同步定时器和异步定时器的使用,包括同步等待与异步等待的区别。此外,还探讨了在多线程环境中如何利用`strand`实现同步回调,以保证线程安全。文章最后给出了多线程同步回调的示例代码,展示了`CPrinter`类的实现及其工作原理。
摘要由CSDN通过智能技术生成

并发与并行: 并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。

1.Timer.1 - 使用同步定时器

先完整介绍一下,后面的例子该省略的就省略了。

所有的Asio类只要简单的包含"asio.hpp"头文件便可使用:

#include <boost/asio.hpp>

因为本程序中使用了定时器,我们需要包含相应的的Boost.Date_Time 头文件来处理时间操作:

#include <boost/date_time/posix_time/posix_time.hpp>

使用Asio的所有程序都至少需要一个提供访问I/O功能的io_service 对象。因此在主函数中我们做的第一件事就是声明一个这个类型的对象:

boost::asio::io_service io;

接下来我们声明一个boost::asio::deadline_timer类型的对象。作为 Asio的核心类,它提供的I/O功能(在此为定时器功能)通常用一个io_service 的引用作为其构造函数的第一个参数。第二个参数设置一个从现在开始5秒后终止的定时器。

boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));

可以看一下boost::asio::deadline_timer的几个构造函数

复制代码
1 basic_deadline_timer(
2 boost::asio::io_service & io_service);
3
4 basic_deadline_timer(
5 boost::asio::io_service & io_service,
6 const time_type & expiry_time);
7
8 basic_deadline_timer(
9 boost::asio::io_service & io_service,
10 const duration_type & expiry_time);
复制代码
注意后两种的区别,说明以下2种用法是等价的:

1 boost::asio::deadline_timer t(io, boost::posix_time::microsec_clock::universal_time()+boost::posix_time::seconds(5));
2 boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));

在这个简单的程序中,我们用定时器演示一个阻塞等待。deadline_timer::wait() 函数调用直到定时器终止(从定时器被创建算起,五秒后终止)才会返回。

一个deadline timer 通常是下面两种状态中的一种:“expired(终止)” 或"not expired(不终止)"。如果deadline_timer::wait() 函数被一个已经终止的定时器调用, 它将立即返回。

t.wait();

最后我们打印出 “Hello, world!” 信息以显示定时器已经终止。

std::cout << “Hello, world!\n”;

代码:

按 Ctrl+C 复制代码

#include
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

int main()
{
boost::asio::io_service io;

boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
t.wait();

std::cout << “Hello, world!\n”;

return 0;
}
按 Ctrl+C 复制代码
2. Timer.2 - 使用异步定时器

本例使用Asio的异步回调功能在定时器中演示一个异步等待。

使用Asio的异步功能意味着当一个异步操作完成时一个回调函数将被调用。在本程序中我们定义一个名为print 的函数,在异步等待结束后这个函数将被调用。

void print(const boost::system::error_code& /e/)
{
std::cout << “Hello, world!\n”;
}

int main()
{
boost::asio::io_service io;

boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));

接下来,我们调用 deadline_timer::async_wait() 函数执行一个异步等待去取代Timer.1例中的阻塞等待。当调用这个函数时我们传入上面定义的print回调句柄。

t.async_wait(print);

最后,我们必须在io_service对象上调用io_service::run()成员函数。

Asio保证回调句柄仅仅能被io_service::run()启动的当前线程所调用。 因此,如果io_service::run() 函数不执行,用于异步等待完成时的回调函数(在本例中为print函数)将永远不会被调用。

当仍旧有“工作”可做时,io_service::run() 函数会继续运行。在本例中,“工作”是定时器的异步等待,因此,直到定时器终止和回调函数执行完成,程序才会返回。

在调用io_service::run()之前确保给 io_service 一些工作去做,这非常重要。 例如,如果我们省略了上面调用的deadline_timer::async_wait() 函数,io_service对象将没有任何事情去做,因此io_service::run() 将立即返回。

io.run();

和同步方式相比,它主要有两点不同:
(1) 调用的是非阻塞函数async_wait,它的入参是一个回调函数。
(2) 显式调用io_service.run()函数驱动异步IO调度。

值得提出的是&#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值