Boost.Asio翻译整理(二)


示例1:

Timer.1 - Using a timer synchronously

使用定时器演示一个阻塞等待

这个示例程序通过展示在定时器中执行一个阻塞等待( blocking wait )来介绍Asio。
让我们从必须包含的头文件开始。
  • 所有的Asio类只要简单的包含"asio.hpp"头文件便可使用。
  • 因为本程序中使用了定时器,我们需要包含相应的的Boost.Date_Time 头文件来处理时间操作。

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

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

说明3: deadline_timer::wait()函数调用直到定时器终止(从定时器被创建算起,五秒后终止)才会返回。
一个deadline timer 通常是下面两种状态中的一种:"expired(终止)" 或"not expired(不终止)"。
deadline_timer::wait()函数如果被一个已经终止的定时器调用, 它将立即返回。

查看本例的全部源码:full source listing

---------------------------------------------------- 分割线 ---------------------------------------------------

示例2:

Timer.2 - Using a timer asynchronously


这个示例程序示范了如何通过修改Timer.1 中的程序,使用Asio的异步回调功能在定时器中演示一个异步等待。

说明:
1, 使用Asio的异步功能意味着当一个异步操作完成时一个回调函数将被调用。在本程序中我们定义一个
名为“print”的函数,在异步等待结束后这个函数将被调用。
2, 必须在io_service对象上调用io_service::run() 成员函数。
Asio保证回调句柄仅仅能被boost::asio::io_service::run()启动的当前线程所调用。因此,
如果boost::asio::io_service::run() 函数不执行,用于异步等待完成时的回调函数(在本例中为print函数)将永远不
会被调用。 当仍旧有“工作”可做时,boost::asio::io_service::run() 函数会继续运行。在本例中,
“工作”是定时器的异步等待,因此,直到定时器终止和回调函数执行完成,程序才会返回。


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


查看本例的全部源码:full source listing

---------------------------------------------------- 分割线 ---------------------------------------------------

示例3:

Timer.3 - Binding arguments to a handler

在本示例程序中我们将修改Timer.2中的例子,使定时器每秒被激活一次。例子将示范如何给你的函数指针传递附加参数。
查看本例的全部源码:full source listing

说明:
1, 需要熟悉了解boost::bind库
2, 使用Asio实现一个重复定时器,你必须在你的回调函数中去改变定时器的终止时间,然后开始一个新的异步等待。
显然这意味着回调函数必须拥有改变定时器对象的权限。为此我们为print函数增加两个新参数。
一个指向定时器对象的指针
一个用于当定时器第6次被激活时我们可以中止程序的计数器
3,在定时器中启动一个新的异步等待。我们必须使用boost::bind() 函数给你的回调函数绑定额外的参数,
因为boost::asio::deadline_timer::async_wait() 函数只期望得到一个拥用
void(constboost::system::error_code&)签名的函数指针(或函数对象)。


在本例中,boost::bind()的boost::asio::placeholders::error参数是为了给回调函数传入一个error对象。
当开始异步操作时,如果使用boost::bind(),你必须指定和回调函数的参数列表相匹配的一个参数。

---------------------------------------------------- 分割线 ----------------------------------------------------------------------

示例4:

在本例中我们将看到怎样使用类成员函数作为回调句柄。程序完成和Timer.3完全同样的功能。

查看本例的全部源码:full source listing

---------------------------------------------------- 分割线 ----------------------------------------------------------------------

示例5:

本示例程序示范了使用boost::asio::strand 类来创建多线程程序中的同步回调句柄。

前四个例程只是在线程下使用boost::asio::io_service::run()函数来避免处理函同步。如你所见,Asio库保证回调句柄仅能被当前正在调用boost::asio::io_service::run()函数的线程调用。因此,在线程中调用boost::asio::io_service::run()能确保回调句柄不被并发运行


单线程通常是使用Asio开发应用程序最好的方式。下面是Asio在程序中的局限性,尤其是服务器方面,包括:

  • 操作需要较长时间处理才能完成时弱响应
  • 在大规模的多处理机系统中表现不佳
如果你发现自己陷入这些局限时,一个可供选择的方法是创建一个每个线程都调用boost::asio::io_service::run()的线程池。不过,因为这允许并发操作,当访问一个共享、非线程安全的资源时,我们需要一个同步方式。
说明:
1,在主函数中,boost::asio::io_service::run() 现在被两个线程调用:主线程和一个附加线程。这一切依赖于boost::thread对象来完成。正如它被一个单线程调用一样,boost::asio::io_service::run() 的并发调用会一直持续到无任何“工作”可做。后台线程直到所有异步操作都完成后才会退出。

2, 在一个多线程程序中,当访问同一共享资源时,异步操作必须是同步的。在本例中,print1和print2函数使用的共享资源为std::cout 和count_数据成员。

3, 除了初始化一对boost::asio::deadline_timer 成员变量外,构造函数还初始化一个boost::asio::strand类型的strand_成员变量。
boost::asio::strand 对象保证:对于通过它来分派执行的众操作中,只有一个操作执行完成之后才允许进入下一个操作。
这种保证与多少个线程调用boost::asio::io_service::run()无关。
当然,如果不是通过一个boost::asio::strand对象分派,或者通过其它不同的boost::asio::strand对象分派,这些操作仍旧可能是并发的

你可能感兴趣的:(boost)