boost::asio::io_service如何确定工作的优先级
How does boost::asio::io_service prioritize work?
我正在使用boost::asio::io_service
来管理一些异步TCP通信。这意味着我创建一个boost::asio::ip::tcp::socket
并赋予它io_service
。当我开始通信时,它的示意图是这样的:
Async Resolve -> Callback -> Async Connect -> Callback -> Async Write -> Callback -> Async Read
我省略了决心和绑定等部分。假设套接字已绑定到端口并且主机名已解析(因此连接意味着建立与端点的实际连接(
现在的重点是,我可能会使用相同的io_service
对象启动多个异步连接。这意味着例如,当我的io_service
线程中程序即将Async Write
一些数据时,主线程将在 Socket 上调用 Async Resolve
(但具有相同的io_service
(。这意味着我的io_service
现在有一些并行的工作要做 - 我想知道的是它将如何确定工作的优先级?
例如,它是这样的
Main Thread | io_service Thread
-------------------------+-----------------------------------------------
SocketA->Async Connect |
//Some other Stuff | SocketA->Callback from Async Connect
| SocketA->Async Write
SocketB->Async Connect |
| --> ?
在这一点上,我不得不承认我不太确定io_service
是如何工作的。在第四行中,现在需要执行两个不同的异步函数。
io_service
能够同时进行Async Connect
和Async Write
吗?如果是这种情况,很明显,总是会调用来自首先完成的函数的回调。
如果io_service
无法做到这一点,它将按什么顺序完成工作?如果首先调用SocketA Async Write
,则也会首先调用它的回调。实际上,在套接字A上的整个操作完成之前,将始终存在工作。
编辑:
根据ereOns的评论,我试图使我的问题更精确一些:
从io_service
线程的角度来看 - SocketA Async Connect
调用是异步的还是同步的?从我的主线程的角度来看,它当然是异步的(它只是调度命令然后继续(。但是在io_service
线程中,这个特定的Connect
调用会阻止其他操作吗?
换句话说:一个io_service
是否能够在读取另一个套接字时连接到一个套接字?
另一个例子是,如果我只在我的 main 函数中调用 2 个Async Connect
,则紧接着彼此:
SocketA->AsyncConnect();
SocketB->AsyncConnect();
假设来自套接字 A 的主机有点慢,需要两秒钟才能回答。因此,当套接字A尝试连接时,套接字B是否也会同时连接,还是必须等到套接字A完成/超时?
所有工作都在运行io_service.run()
线程中完成。
但是,对任何async_
方法的调用都不会阻止此特定线程:它的行为与io_service.run()
在多个事件上调用select()
完全相同,并且在引发此类事件时"返回"(调用回调(。也就是说,如果您调用:
socketA->async_connect();
socketB->async_connect();
socketB
也可以在socketA
之前连接,然后首先调用关联的回调,仍在线程io_service.run()
运行中。
这就是 Boost Asio 的所有美妙之处:它非常关心投票、等待和在更合适的时候引发事件,留给你"简单"的部分。
您不应该尝试在此处预测异步操作的执行顺序。 async_connect
只是向io_service
发出信号并立即返回。真正的工作是在对象的事件处理循环(io_service::run
(中完成io_service
但你不知道确切的细节。它很可能使用特定于操作系统的异步 IO 函数。
目前尚不清楚您要实现的目标。也许您应该使用同步操作。也许您应该使用线程同步功能。也许io_service::run_one
会帮助你(它最多执行一个处理程序(。
也许您希望在单独的线程中多次调用io_service::run
,从而创建一个线程池。这样,一个长完成处理程序就不会阻止所有其他处理程序。
boost::asio::io_service service;
const size_t ASIO_THREAD_COUNT = 3;
boost::thread_group threadGroup;
for (size_t i = 0; i < ASIO_THREAD_COUNT; ++i)
threadGroup.create_thread(boost::bind(&boost::asio::io_service::run,
&service, boost::system::error_code()));
- QSqlquery prepare()和bindvalue()不工作
- 如何确定我已使用非编码文件到达 EOF?
- 导入库可以跨dll版本工作吗
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 代码在 CodeSignal 中工作不正确。不确定这是否是我的代码缺陷
- C++编译器 g++.exe 无法编译简单的测试程序 - 确定 CXX 编译器是否工作失败
- QtCUrl post不再工作(Linux nok...窗口确定)
- 程序停止工作,指针错误我确定
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?
- 不确定无序映射是如何工作的
- 我如何使用关系 btwn 3 整数来确定三角形和/或我可以使用什么声明来使这个程序工作
- 什么是C++中的不确定行为?它与未定义的行为有何不同
- 如何确定流程的"经理"和"工作线程"线程的优先级(或为其设置调度策略)?
- C++ & boost::threads - 如何根据工作类型确定线程的优先级?
- 不确定查找功能在 CPP 中的工作原理
- boost::asio::io_service如何确定工作的优先级