boost :: asio :: io如何?
我使用boost::asio::io_service
来管理一些异步TCP通信。 这意味着我创建一个boost::asio::ip::tcp::socket
并将io_service
赋予它。 当我开始沟通时,它就是这样示意的:
Async Resolve -> Callback -> Async Connect -> Callback -> Async Write -> Callback -> Async Read
我省略了像解析和绑定等部分。 假设Socket已经被绑定到一个端口并且主机名被解析了(所以连接意味着建立到端点的真实连接)
现在重点是我可以用同一个io_service
对象启动多个Async连接。 这意味着,例如,在我的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
将被首先调用,它的回调SocketA Async Write
也会首先被调用。 事实上,在SocketA的整个操作完成之前,总会有工作。
编辑:
根据ereOns的评论,我尝试让我的问题更精确一些:
从io_service
线程的角度来看 - SocketA Async Connect
调用是异步的还是同步的? 从我的主线程来看,它当然是异步的(它只是分派命令,然后继续)。 但是在io_service
线程中这个特定的Connect
调用会阻止其他操作吗?
换句话说:一个单一的io_service
可以在另一个套接字上读取时连接到一个套接字?
另一个例子是,如果我在主函数中相互调用2个Async Connect
:
SocketA->AsyncConnect();
SocketB->AsyncConnect();
假设来自SocketA的Host有点慢,需要两秒钟才能回答。 所以,虽然SocketA试图连接,同时SocketB也会连接,或者它将不得不等待,直到SocketA完成/超时?
所有的工作都在io_service.run()
运行的线程中完成。
但是,对任何async_
方法的调用都不会阻止这个特定的线程:它的行为与io_service.run()
select()
在几个事件上调用select()
完全相同,并且在发生这样的事件时“返回”(调用回调)。 也就是说,如果你打电话给:
socketA->async_connect();
socketB->async_connect();
socketB
最好在socketA
之前连接,然后首先调用相关的回调socketA
,仍然在线程io_service.run()
运行。
这就是Boost Asio的全部美妙之处:当它更合适时,它需要非常好地关注投票,等待和提高事件,让您拥有“轻松”的部分。
这里不应该尝试预测异步操作的执行顺序。 async_connect
只是发信号给io_service
并立即返回。 真正的工作是在io_service
对象的事件处理循环( io_service::run
)中完成的,但您不知道确切的细节。 它很可能使用OS特定的异步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()));
链接地址: http://www.djcxy.com/p/10745.html
下一篇: Java Based GUI Automation (Not limited to Java based GUI like Swing)