关于asio中的io_service::run函数在没有任务时退出的问题

本文介绍如何使用Boost.Asio的work对象使io_service::run函数在无任务时持续运行而不立即返回。通过实例展示了如何在WTL项目中正确设置io_service及work对象,并保持线程运行直到工作对象被销毁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

io_service::run函数在没有任何任务的时候将会自动返回,这对于WTL的项目来说并不方便,之前我有一篇文章讲到使用一个循环来运行该run函数,那是十分不优雅的。今天在网上再次查找办法,终于找到io_service::work类可以使io_service::run函数在没有任务的时候仍然不返回,直至work对象被销毁。

boost::asio::io_service ios;
boost::asio::io_service::work work(ios); // 使用work对象
ios.run(); // 就算是当前没有任务,ios.run()也不会马上返回


或者,下面从我的程序中直接拷贝出来的例子,该程序使用WTL框架

boost::asio::io_service m_ios;
std::shared_ptr<boost::thread> m_ios_thread;
std::shared_ptr<tm_client> m_client_ptr;
std::shared_ptr<boost::asio::io_service::work> m_work;
 
m_work.reset(new boost::asio::io_service::work(m_ios));
m_ios_thread.reset(new boost::thread(boost::bind(&boost::asio::io_service::run, &m_ios)));
 
// resolve the hostname
boost::asio::ip::tcp::resolver resolver(m_ios);
boost::asio::ip::tcp::resolver::query q(hostname, boost::lexical_cast<std::string>(x::tl::PORT_TMSRV));
boost::asio::ip::tcp::resolver::iterator res_begin = resolver.resolve(q), res_end;
 
if (res_begin != res_end)
{
  // constructor client connection object
  m_client_ptr.reset(new tm_client(m_ios, tm_window_notifier(*this)));
  m_client_ptr->connect(*res_begin);
}


另外可以参考文章:Stopping the io_service from running out of work


From: http://btblog.net/?p=50

<think>我们正在讨论Boost.Asio中的io_service(在较新版本中称为io_context)的核心概念和作用。根据用户的问题,我们需要解释io_service是什么以及它在异步I/O编程中的作用。同,用户提供的引用材料[1]和[2]虽然不完全匹配,但可以辅助理解。 首先,io_service是Boost.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 实现高性能网络编程的核心组件。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值