【Boost】boost库asio详解2——io_service::run函数无任务时退出的问题

本文介绍如何使用 Boost.Asio 的 io_service::work 类使 io_service::run 在无任务时保持阻塞状态,直到 work 对象被销毁。通过对比有无 work 对象时的不同表现,展示了该机制的作用。

转载于http://blog.youkuaiyun.com/huang_xw/article/details/8471057

io_service::work类可以使io_service::run函数在没有任务的时候仍然不返回,直至work对象被销毁。

  1. void test_asio_nowork()  
  2. {  
  3.     boost::asio::io_service ios;  
  4.   
  5.     PRINT_DEBUG("ios before");  
  6.     ios.run();  
  7.     PRINT_DEBUG("ios end");  
  8. }  
  9.   
  10. void test_asio_work()  
  11. {  
  12.     boost::asio::io_service ios;  
  13.     // 增加一个work对象  
  14.     boost::asio::io_service::work work(ios);  
  15.   
  16.     PRINT_DEBUG("ios before");  
  17.     // 当没有任务时,ios.run()也不会马上返回  
  18.     ios.run();  
  19.     PRINT_DEBUG("ios end");  
  20. }  
test_asio_nowork()执行结果:
  1. 2013-01-05 22:43:19 334 [4868] DEBUG - ios before  
  2. 2013-01-05 22:43:19 341 [4868] DEBUG - ios end  
test_asio_work()的执行结果:
  1. 2013-01-05 22:43:48 514 [7852] DEBUG - ios before  
  2.    

没有任务时, 也会阻塞.


<think>我们正在讨论Boost.Asio中的io_service(在较新版本中称为io_context)的核心概念和作用。根据用户的问题,我们需要解释io_service是什么以及它在异步I/O编程中的作用。同,用户提供的引用材料[1]和[2]虽然不完全匹配,但可以辅助理解。 首先,io_serviceBoost.Asio的核心,它负责提供I/O功能的事件循环和任务调度。其主要作用包括: 1. 事件循环:处理异步I/O事件(如套接字读写完成、定器到期等)。 2. 任务调度:允许用户投递(post)自定义任务到事件循环中执行。 接下来,结合引用材料: - 引用[1]提到:Boost.Asio执行“工作”(work)并通知应用程序。这体现了io_service的事件处理机制。 - 引用[2]提到:post和dispatch的区别,说明任务调度的执行策略(立即执行或排队执行)。 因此,回答将围绕这些点展开,并强调io_service在异步编程中的核心地位。 最后,生成相关问题以扩展用户对io_service的理解。</think>### Boost.Asio 的 `io_service` 概念与作用详解 `io_service`(在新版 Boost.Asio 中重命名为 `io_context`)是 **异步 I/O 操作的核心调度器**,本质上是一个**事件循环引擎**。它负责管理所有异步操作的任务队列、事件分发和回调执行,是 Boost.Asio 异步编程的基石。 --- ### 一、核心作用 #### 1. **I/O 事件调度中心** - 管理所有异步操作(套接字读写、定器、信号等)的事件队列 - 通过 `run()` 方法启动事件循环,阻塞线程直到所有任务完成: ```cpp boost::asio::io_service io; io.run(); // 启动事件循环(阻塞) ``` - 当有 I/O 事件就绪,自动调用对应的回调函数(处理程序) #### 2. **任务队列管理器** - 支持通过 `post()` 或 `dispatch()` 添加自定义任务: ```cpp io.post([](){ std::cout << "任务被执行" << std::endl; }); // 添加任务到队列 ``` - `post()` 与 `dispatch()` 的区别[^2]: - `post()`:任务**总是加入队列**,等待下次事件循环执行 - `dispatch()`:若在 `io_service` 关联线程中调用,则**立即执行**;否则加入队列 #### 3. **资源生命周期控制器** - 管理所有异步操作的资源(如套接字、定器) - 通过 `work` 对象防止事件循环提前退出: ```cpp boost::asio::io_service::work work(io); // 保持事件循环活跃 io.run(); // 即使无任务也持续运行 ``` --- ### 二、工作流程解析 1. **投递任务** - 用户通过 `async_*` 函数(如 `async_read`)或 `post()` 提交任务 2. **事件循环启动** - 调用 `run()` 启动线程的事件循环 3. **事件监听与分发** - 操作系统通知 I/O 事件就绪 → `io_service` 将回调加入执行队列 4. **回调执行** - 在 `run()` 线程中按顺序执行回调函数 - 若使用 `io_service::strand` 可保证线程安全 > 关键特性:**非阻塞异步模型**。当调用 `async_read(socket, buffer, handler)` 函数立即返回,实际读写操作由操作系统在后台执行。操作完成后,`io_service` 将 `handler` 加入队列,由 `run()` 线程调用[^1]。 --- ### 三、典型应用场景 ```cpp // 创建 io_service 和 TCP 接收器 boost::asio::io_service io; boost::asio::ip::tcp::acceptor acceptor(io, endpoint); // 异步接受连接 acceptor.async_accept([](boost::system::error_code ec, tcp::socket socket) { if (!ec) { // 新连接处理逻辑 } }); // 启动事件循环(通常用多线程处理) std::thread t([&io](){ io.run(); }); t.join(); ``` 1. **高并发服务器** - 单线程 `io_service` 可处理数千并发连接(通过异步 I/O) 2. **定任务调度** ```cpp boost::asio::deadline_timer timer(io, boost::posix_time::seconds(1)); timer.async_wait([](...){ /* 定任务 */ }); ``` 3. **跨线程任务同步** - 通过 `post()` 实现线程间安全的任务传递 --- ### 四、性能优化要点 1. **多线程运行** - 单个 `io_service` 可由多线程同调用 `run()`: ```cpp std::vector<std::thread> threads; for (int i = 0; i < 4; ++i) { threads.emplace_back([&io](){ io.run(); }); } ``` - 线程数建议与 CPU 核心数匹配 2. **避免回调阻塞** - 回调函数必须**非阻塞**,否则会拖慢整个事件循环 - 耗任务应投递到专用线程池 3. **使用 `strand` 同步** - 当多线程访问共享资源: ```cpp boost::asio::io_service::strand strand(io); strand.post([](){ /* 线程安全操作 */ }); ``` --- ### 五、与操作系统的交互 `io_service` 底层封装了操作系统的 I/O 多路复用机制: - Linux: `epoll` - Windows: `IOCP` - macOS: `kqueue` 其通过**就绪事件通知机制**实现高效 I/O 调度,避免轮询造成的 CPU 浪费[^1]。 > 总结:**`io_service` = 异步任务队列 + 事件分发器 + 资源管理器**,是 Boost.Asio 实现高性能网络编程的核心组件。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值