简体   繁体   English

boost :: asio :: io_service如何优先工作?

[英]How does boost::asio::io_service prioritize work?

I am using boost::asio::io_service to manage some asynchronous TCP communication. 我使用boost::asio::io_service来管理一些异步TCP通信。 That means I create a boost::asio::ip::tcp::socket and give the io_service to it. 这意味着我创建了一个boost::asio::ip::tcp::socket并将io_service给它。 When I start the communication it goes schematically like this: 当我开始沟通时,它会像这样示意:

Async Resolve -> Callback -> Async Connect -> Callback -> Async Write -> Callback -> Async Read

I ommitted parts like resolve and bind. 我省略了像resolve和bind这样的部分。 Just assume the Socket has been bound to a port and the hostname is resolved ( so connect meaning establishing the real connection to the endpoint ) 假设Socket已绑定到端口并且主机名已解析(因此连接意味着建立与端点的真实连接)

Now the point is that I may start several Async Connections with the same io_service object. 现在重点是我可以使用相同的io_service对象启动多个异步连接。 This means for example, that while in my io_service thread the program is about to Async Write some data, the main thread will call Async Resolve with on Socket ( but with the same io_service ). 这意味着,例如,在我的io_service线程中,程序即将Async Write一些数据,主线程将在Socket上调用Async Resolve (但使用相同的io_service )。 This means that my io_service now has some parallel work to do - what I'd like to know is how it will prioritize the work? 这意味着我的io_service现在有一些并行的工作要做 - 我想知道它是如何优先工作的?

For example it go like this 例如,它是这样的

Main Thread              |      io_service Thread
-------------------------+-----------------------------------------------
SocketA->Async Connect   |
//Some other Stuff       |     SocketA->Callback from Async Connect
                         |     SocketA->Async Write
SocketB->Async Connect   |      
                         |     --> ?

Now at this point I have to admit I am not quite sure how the io_service works. 现在,在这一点上,我不得不承认我不太确定io_service是如何工作的。 In the fourth line there are now two different asynchronous functions which needs to be executed. 在第四行中,现在有两个不同的异步函数需要执行。

Is io_service capable of doing the Async Connect and the Async Write simultaneously? io_service是否能够同时执行Async ConnectAsync Write If that is the case it is clear that always the callback from the function which is finished first will be called. 如果是这种情况,很明显始终会调用首先完成的函数的回调。

If the io_service is not capable of doing so, in which order will it do the work? 如果io_service 无法这样做,它将以哪种顺序完成工作? If SocketA Async Write will be called first, it's callback will also be called first. 如果SocketA Async Write调用SocketA Async Write则首先调用它的回调。 Actually there will be always work until the whole operation on SocketA is finished. 实际上,在SocketA的整个操作完成之前总会有效。

EDIT : 编辑:

According to ereOns comment I try to make my question a bit more precise: 根据ereOns的评论,我试着让我的问题更准确一些:

From the view of the io_service thread - is the SocketA Async Connect call asynchronous or synchronous? io_service线程的角度来看 - SocketA Async Connect调用是异步还是同步? From the view of my main thread it is of course asynchronous ( it just dispatches the command and then goes on ). 从我的主线程的角度来看,它当然是异步的(它只是调度命令然后继续)。 But in the io_service thread will this specific Connect call block other operations? 但是在io_service线程中这个特定的Connect调用会阻塞其他操作吗?

In other words: Is one single io_service capable of Connecting to one Socket while it is reading on another? 换句话说:一个单独的io_service能够在另一个Socket读取时连接到一个Socket?

Another example would be if I just call 2 Async Connect in my main function right after each other: 另一个例子是,如果我只是在我的主函数中直接调用2个Async Connect

SocketA->AsyncConnect();
SocketB->AsyncConnect();

Let's say the Host from SocketA is a bit slow and it takes it two seconds to answer. 假设来自SocketA的主机有点慢,需要两秒钟才能回答。 So while SocketA is trying to connect would SocketB in the meanwhile also connect or would it have to wait until SocketA is done /timed out? 因此,虽然SocketA试图连接,同时SocketB也会连接,还是必须等到SocketA完成/超时?

All the work is done in the thread where io_service.run() runs. 所有工作都在io_service.run()运行的线程中完成。

However, the call to any async_ method won't block this specific thread: it behaves exactly like if io_service.run() called select() on several events, and "returns" (calls a callback) whenever such an event is raised. 但是,对任何async_方法的调用都不会阻止这个特定的线程:它的行为与io_service.run() select()在几个事件上调用select()完全相同,并且只要引发这样的事件就“返回”(调用回调)。 That is, if you call: 也就是说,如果你打电话:

socketA->async_connect();
socketB->async_connect();

socketB may as well connect before socketA and the associated callback would then be called first, still in the thread io_service.run() runs. socketB也可以在socketA之前连接,然后首先调用相关的回调,仍然在线程io_service.run()运行。

That's all the beauty of Boost Asio: it takes a very good care about polling, waiting and raising events when it is more appropriate, leaving you with the "easy" part. 这就是Boost Asio的美妙之处:在更合适的情况下,它需要非常关注投票,等待和提升事件,让你拥有“轻松”的部分。

You shouldn't try to predict order of execution for asynchronous operations here. 您不应该尝试在此预测异步操作的执行顺序。 async_connect just signals to io_service and returns immediately. async_connect只是向io_service发出信号并立即返回。 The real work gets done in io_service object's event processing loop ( io_service::run ), but you don't know exact specifics. 真正的工作是在io_service对象的事件处理循环( io_service::run )中完成的,但是你不知道确切的细节。 It most likely uses OS-specific asynchronous IO functions. 它最有可能使用特定于操作系统的异步IO功能。

It's not clear what you're trying to achieve. 目前尚不清楚你想要实现的目标。 Maybe you should use synchronous operations. 也许你应该使用同步操作。 Maybe you should use thread synchronization functionality. 也许你应该使用线程同步功能。 Maybe io_service::run_one will help you (it executes at most one handler). 也许io_service::run_one会帮助你(它最多执行一个处理程序)。

Maybe you'll want to call io_service::run multiple times in separate threads, creating a thread pool. 也许你想在不同的线程中多次调用io_service::run ,创建一个线程池。 That way one long completion handler won't block all the others. 这样一个长的完成处理程序将不会阻止所有其他处理程序。

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()));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM