并发与并行: 并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。
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";
代码:
1 #include <iostream>
2 #include <boost/asio.hpp>
3 #include <boost/date_time/posix_time/posix_time.hpp>
4
5 int main()
6 {
7 boost::asio::io_service io;
8
9 boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
10 t.wait();
11
12 std::cout << "Hello, world!\n";
13
14 return 0;
15 }
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();