Boost库学习笔记(2)—— Asio

一、概述

        Boost.Asio是一个用于网络和底层I/O编程的跨平台的C++库,它使用了现代的C++方法,为开发人员提供了一致的异步模型。使用前须知
        要使用Asio库,只需要代码中包含头文件:#include <boost/asio.hpp>,Boost.Asio依赖如下的库:

  • Boost.System:这个库为Boost库提供操作系统支持(http://www.boost.org/doc/libs/1_51_0/doc/html/boost_system/index.html
  • Boost.Regex:使用这个库(可选的)以便你重载read_until()或者async_read_until()时使用boost::regex参数。
  • Boost.DateTime:使用这个库(可选的)以便你使用Boost.Asio中的计时器。
  • OpenSSL:使用这个库(可选的)以便你使用Boost.Asio提供的SSL支持。

二、boost::asio::io_context

(1)io_context类为异步I/O对象提供核心功能,对象包括:

  • boost::asio::ip::tcp::socket
  • boost::asio::ip::tcp::acceptor
  • boost::asio::ip::udp::socket
  • boost::asio::deadline_timer

(2)提交任务请求函数
        通过以下函数向io_context提交任务请求(官方建议不要使用io_context自带的成员函数defer()dispatch()post(),因为它们即将被移除),其中参数handler可以是函数对象,也可以是lambda表达式:

  • boost::asio::defer(io_context, handler);
  • boost::asio::dispatch(io_context, handler);
    向io_context请求执行handler并立即返回,io_context保证handler只会在run()poll()接口执行的线程中被调用,dispatch()接口内部不会调用handler(但是如果run()poll()接口执行是在当前线程执行,则dispatch()内部会调用handler)。
  • boost::asio::post(io_context, handler);
    向io_context请求执行handler并立即返回,io_context保证handler只会在run()poll()接口执行的线程中被调用,post()接口内部不会调用handler

(3)任务处理函数

  • count_type run();
    1、执行事件循环,程序将被阻塞到任务被完成且再没有其他任务,或者直到io_context调用stop()停止为止。
    2、多线程中可以调用run()来开启一个线程池,io_context可以在线程池中执行handler。线程池中等待的所有线程都是等效的,io_context可以选择其中的任何一个线程来调用handler
    3、在run()正常退出后立即调用run()poll()将会立即返回,除非在调用这些函数前调用restart()
    4、函数将返回被处理的handler数量。
  • std::size_t run_for(const chrono::duration<Rep, Period>& rel_time);
    在一定时间内处理事件循环,阻塞到任务被完成且没用其他任务,或者直到io_context调用stop()停止,或者超时为止。参数rel_time表示时间段。
  • std::size_t run_until(const chrono::time_point<Clock, Duration>& abs_time);
    在一定时间内处理事件循环,阻塞到任务被完成且没用其他任务,或者直到io_context调用stop()停止,或者到达某个时间点为止。参数abs_time表示阻塞到某个时间点。
  • count_type run_one();
    std::size_t run_one_for(const chrono::duration<Rep, Period>& rel_time);
    std::size_t run_one_until(const chrono::time_point<Clock, Duration>& abs_time);
    最多处理一个任务, 处理完就退出,或者io_context被停止。
  • count_type poll();
    以非阻塞方式执行事件循环,处理已就绪的任务,当没有其他已就绪的任务或者io_context被停止时返回。
  • count_type poll_one();
    以非阻塞方式处理任务,最多处理一个。

(4)其他函数

  • void stop();
    停止事件处理循环,非阻塞,只是向io_context发出停止信号。调用该函数后,再调用run()poll()将会立即返回,不会处理任任何handler,直到调用restart()
  • bool stopped() const;
    用于判断io_context当前是否已停止,当已停止时,调用run()poll()将立即返回,不会处理任任何handler
  • void restart();
    重新启动io_context,为后续调用run()poll()做准备。

三、boost::asio::executor_work_guard、boost::asio::io_context::work

        io_context在执行run()后,如果没有I/O事件将会退出事件循环。但更多时候,我们希望run()函数的事件循环在没有I/O事件的情况下,也不会退出事件循环,而是一直等待,当有了新的异步I/O调用的时候,还可以继续使用该循环。
(1)方法1
        executor_work_guard的构造和析构分别调用了executor_.on_work_started();executor_.on_work_finished();
        executor_是executor_work_guard绑定的io_context对象,而on_work_started才是真正保证即使io_context中没有任务的时候,run()也不退出的关键。所以可以通过操控executor_work_guard生命周期的方法,来控制run()什么时候退出。示例:

boost::asio::io_context ctx;
boost::asio::executor_work_guard<asio::io_context::executor_type> worker = boost::asio::make_work_gurad(ctx);
std::thread th([&ctx]() {
	ctx.run();
});
...
worker.reset(); /* 允许run()退出 */

(2)方法2
        work类的核心就是防止io_context在没有I/O事件的时退出。直接使用boost::asio::io_context::work(boost::asio::io_context& io_context);的方式进行构造,当work对象被销毁时,它的作用就自动停止了。示例:

boost::asio::io_context ctx;
boost::asio::io_context::work worker(ctx);
std::thread th([&ctx]() {
	ctx.run();
});
ctx.stop(); /* 先显式停止io_context, 否则无法终止 */
th.join();

四、boost::asio::detail::thread_group

        线程池,可以预先创建指定线程个数,没有detach()接口。示例:

boost::asio::io_context ctx;
boost::asio::io_context::work worker(ctx);
boost::asio::detail::thread_group threadPool;
threadPool.create_threads([&] {
	ctx.run();
}, 16); /* 创建16个线程 */
threadPool.join();
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值