在多个windows :: basic_handle上,WaitForMultipleObjects和boost :: asio有什么区别? [英] What's the difference between WaitForMultipleObjects and boost::asio on multiple windows::basic_handle's?

查看:103
本文介绍了在多个windows :: basic_handle上,WaitForMultipleObjects和boost :: asio有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由许多不同的IO设备控制的HANDLE列表.之间的(性能)差异是什么?

I have a list of HANDLE's, controlled by a lot of different IO devices. What would be the (performance) difference between:

  1. 在所有这些句柄上调用WaitForMultipleObjects
  2. 在boost :: windows :: basic_handle上的async_read遍及所有这些句柄

WaitForMultipleObjects O(n)的时间复杂度为n个句柄吗?
您可以以某种方式在windows :: basic_handle上调用async_read对吗?还是这个假设是错误的?
如果我在多个线程中的同一IO设备上运行调用,那么这些线程之间的处理调用是否会保持平衡?那将是使用asio的主要好处.

Is WaitForMultipleObjects O(n) time complex with n the amount of handles?
You can somehow call async_read on a windows::basic_handle right? Or is that assumption wrong?
If I call run on the same IO device in multiple threads, will the handling-calls be balanced between those threads? That would be a major benefit of using asio.

推荐答案

,因为听起来您从asio继承的主要用途是它建立在IO完成端口(简称iocp)之上.因此,让我们开始比较iocp和WaitForMultipleObjects().这两种方法与Linux上的selectepoll基本上相同.

since it sounds like the main use you would derive from asio is the fact that it is built on top of IO completion ports (iocp for short). So, let's start with comparing iocp with WaitForMultipleObjects(). These two approaches are essentially the same as select vs. epoll on linux.

iocp解决了WaitForMultipleObjects的主要缺点是无法缩放许多文件描述符.它是O(n),因为对于收到的每个事件,您都会再次传递完整的数组,并且内部的WaitForMultipleObjects必须扫描该数组以知道要触发哪个句柄.

The main drawback of WaitForMultipleObjects that was solved by iocp is the inability to scale with many file descriptors. It is O(n), since for each event you receive you pass in the full array again, and internally WaitForMultipleObjects must scan the array to know which handles to trigger on.

但是,由于第二个缺点,这很少出现问题. WaitForMultipleObjects()对它可以等待的最大句柄数有限制(MAXIMUM_WAIT_OBJECTS).此限制是64个对象(请参见winnt.h).通过创建Event对象并为每个事件绑定多个套接字,然后等待64个事件,可以通过多种方法来解决此限制.

However, this is rarely a problem because of the second drawback. WaitForMultipleObjects() has a limit on the max number of handles it can wait on (MAXIMUM_WAIT_OBJECTS). This limit is 64 objects (see winnt.h). There are ways around this limit by creating Event objects and tying multiple sockets to each event, and then wait on 64 events.

第三个缺点是WaitForMultipleObjects()中实际上存在一个细微的错误".它返回触发事件的句柄的索引.这意味着它只能将单个事件传达回用户.这不同于select,后者将返回触发事件的所有文件描述符. WaitForMultipleObjects扫描传递给它的句柄,并返回引发事件的 first 句柄.

The third drawback is that there's actually a subtle "bug" in WaitForMultipleObjects(). It returns the index of the handle which triggered an event. This means it can only communicate a single event back to the user. This is different from select, which will return all file descriptors that triggered an event. WaitForMultipleObjects scans the handles passed in to it and return the first handle that has its event raised.

这意味着,如果您正在等待10个非常活动的套接字,而大多数情况下所有这些套接字都具有一个事件,则对服务传递给WaitForMultipleObjects的列表中的第一个套接字会有很大的偏见. .可以通过以下方法来避免这种情况:每次函数返回并为事件提供服务后,以0超时再次运行它,但这一次仅将数组1的一部分传递给触发的事件.重复操作,直到访问完所有句柄为止,然后返回具有所有句柄和实际超时的原始调用.

This means, if you are waiting on 10 very active sockets, all of which has an event on them most of the time, there will be a very heavy bias toward servicing the first socket in the list passed in to WaitForMultipleObjects. This can be circumvented by, every time the function returns and the event has been serviced, run it again with a timeout of 0, but this time only pass in the part of the array 1 past the event that triggered. Repeatedly until all handles has been visited, then go back to the original call with all handles and an actual timeout.

iocp解决了所有这些问题,并且还引入了一个接口,用于更通用的事件通知,这非常好.

iocp solves all of these problems, and also introduces an interface for a more generic event notification, which is quite nice.

使用iocp(并因此使用asio):

With iocp (and hence asio):

  1. 您不再重复感兴趣的句柄,只告诉一次窗口,它就会记住它.这意味着它在使用多个手柄时可扩展性更好.
  2. 您没有可以等待的句柄数量限制
  3. 您会得到所有事件,即,对于任何特定的句柄都没有偏见

我不确定您是否在自定义句柄上使用async_read的假设.您可能必须测试一下.如果您的手柄指向插座,我想它会起作用.

I'm not sure about your assumption of using async_read on a custom handle. You might have to test that. If your handle refers to a socket, I would imagine it would work.

关于线程问题;是的.如果在多个线程中run() io_service,则事件将分派到空闲线程,并且将随着更多线程而扩展.这是iocp的功能,它甚至具有线程池API.

As for the threading question; yes. If you run() the io_service in multiple threads, events are dispatched to a free thread, and will scale with more threads. This is a feature of iocp, which even has a thread pool API.

简而言之:我相信asio或iocp会提供比仅使用WaitForMultipleObjects更好的性能,但是该性能是否使您受益,主要取决于您拥有多少个句柄以及它们的活跃程度.

In short: I believe asio or iocp would provide better performance than simply using WaitForMultipleObjects, but whether or not that performance will benefit you mostly depends on how many handles you have and how active they are.

这篇关于在多个windows :: basic_handle上,WaitForMultipleObjects和boost :: asio有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆