Boost_Asio(3) post和dispatch

本文通过两个示例对比了Boost.Asio中post与dispatch的区别。post将任务加入处理队列并立即返回,而dispatch则即时请求io_service执行任务。文章展示了如何使用智能指针和互斥锁来管理资源和线程安全。

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

// asio_post_dispatch.cpp : 定义控制台应用程序的入口点。
//
/*
	代码使用智能指针控制io_service,使用mutex控制各个进程间的输出互斥。work类维持io_service的生命周期, 然后使用post添加执行任务。

	在此基础上我们再查看post与dispatch的区别:

	post 优先将任务排进处理队列,然后返回,任务会在某个时机被完成。

	dispatch会即时请求io_service去调用指定的任务。
*/
#include "stdafx.h"
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>

boost::mutex global_stream_lock;

void WorkerThread(boost::shared_ptr< boost::asio::io_service > io_service)
{
	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id()
		<< "] Thread Start" << std::endl;
	global_stream_lock.unlock();

	io_service->run();

	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id()
		<< "] Thread Finish" << std::endl;
	global_stream_lock.unlock();
}

size_t fib(size_t n)
{
	if (n <= 1)
	{
		return n;
	}
	boost::this_thread::sleep(
		boost::posix_time::milliseconds(1000)
		);
	return fib(n - 1) + fib(n - 2);
}

void CalculateFib(size_t n)
{
	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id()
		<< "] Now calculating fib( " << n << " ) " << std::endl;
	global_stream_lock.unlock();

	size_t f = fib(n);

	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id()
		<< "] fib( " << n << " ) = " << f << std::endl;
	global_stream_lock.unlock();
}

int main(int argc, char * argv[])
{
	boost::shared_ptr< boost::asio::io_service > io_service(
		new boost::asio::io_service
		);
	boost::shared_ptr< boost::asio::io_service::work > work(
		new boost::asio::io_service::work(*io_service)
		);

	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id()
		<< "] The program will exit when all work has finished."
		<< std::endl;
	global_stream_lock.unlock();

	boost::thread_group worker_threads;
	for (int x = 0; x < 2; ++x)
	{
		worker_threads.create_thread(
			boost::bind(&WorkerThread, io_service)
			);
	}

	io_service->post(boost::bind(CalculateFib, 3));
	io_service->post(boost::bind(CalculateFib, 4));
	io_service->post(boost::bind(CalculateFib, 5));

	work.reset();

	worker_threads.join_all();

	system("pause");
	return 0;
}
// aiso_dispatch.cpp : 定义控制台应用程序的入口点。
//
/*
	我们可以看到结果是先显示dispatch的结果然后才显示post结果,与预想的是一致的.
*/
#include "stdafx.h"

#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>

boost::mutex global_stream_lock;

void WorkerThread(boost::shared_ptr< boost::asio::io_service > io_service)
{
	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id()
		<< "] Thread Start" << std::endl;
	global_stream_lock.unlock();

	io_service->run();

	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id()
		<< "] Thread Finish" << std::endl;
	global_stream_lock.unlock();
}

void Dispatch(int x)
{
	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id() << "] "
		<< __FUNCTION__ << " x = " << x << std::endl;
	global_stream_lock.unlock();
}

void Post(int x)
{
	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id() << "] "
		<< __FUNCTION__ << " x = " << x << std::endl;
	global_stream_lock.unlock();
}

void Run3(boost::shared_ptr< boost::asio::io_service > io_service)
{
	for (int x = 0; x < 3; ++x)
	{
		io_service->dispatch(boost::bind(&Dispatch, x * 2));
		io_service->post(boost::bind(&Post, x * 2 + 1));
		boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
	}
}

int main(int argc, char * argv[])
{
	boost::shared_ptr< boost::asio::io_service > io_service(
		new boost::asio::io_service
		);
	boost::shared_ptr< boost::asio::io_service::work > work(
		new boost::asio::io_service::work(*io_service)
		);

	global_stream_lock.lock();
	std::cout << "[" << boost::this_thread::get_id()
		<< "] The program will exit when all  work has finished." << std::endl;
	global_stream_lock.unlock();

	boost::thread_group worker_threads;
	for (int x = 0; x < 1; ++x)
	{
		worker_threads.create_thread(boost::bind(&WorkerThread, io_service));
	}

	io_service->post(boost::bind(&Run3, io_service));

	work.reset();

	worker_threads.join_all();

	system("pause");
	return 0;
}


<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]提到:postdispatch的区别,说明任务调度时的执行策略(立即执行或排队执行)。 因此,回答将围绕这些点展开,并强调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、付费专栏及课程。

余额充值