Pie*_*ter 5 c++ multithreading boost-asio waitformultipleobjects
我有一个HANDLE列表,由许多不同的IO设备控制.什么是(性能)差异:
WaitForMultipleObjects O(n)时间是否与n的句柄数量复杂?
你可以在Windows :: basic_handle上以某种方式调用async_read吗?或者这个假设是错的?
如果我在多个线程中调用同一IO设备上运行,那么这些线程之间的处理调用是否会平衡?这将是使用asio的主要好处.
Arv*_*vid 10
因为它听起来像你从asio派生的主要用途是它建立在IO完成端口之上(简称iocp).那么,让我们从比较iocp开始吧WaitForMultipleObjects().这两种方法select与epolllinux上的版本基本相同.
WaitForMultipleObjectsiocp解决了这个问题的主要缺点是无法使用许多文件描述符进行扩展.它是O(n),因为对于您收到的每个事件,您再次传入完整数组,并且内部WaitForMultipleObjects必须扫描数组以了解要触发的句柄.
然而,由于第二个缺点,这很少成为问题.WaitForMultipleObjects()对它可以等待的最大句柄数有限制(MAXIMUM_WAIT_OBJECTS).此限制是64个对象(请参阅winnt.h).通过创建Event对象并将多个套接字绑定到每个事件,然后等待64个事件,可以绕过此限制.
第三个缺点是,实际上存在一个微妙的"错误" WaitForMultipleObjects().它返回触发事件的句柄的索引.这意味着它只能将单个事件传回给用户.这与select将返回触发事件的所有文件描述符不同.WaitForMultipleObjects扫描传入其中的句柄并返回引发其事件的第一个句柄.
这意味着,如果您正在等待10个非常活跃的套接字,所有套接字在大多数情况下都会在它们上面发生事件,那么对于传入的列表中的第一个套接字的服务将会有很大的偏见WaitForMultipleObjects.每次函数返回并且事件已经被服务时,可以通过超时0再次运行它来规避这一点,但这次只传递数组1中触发事件的部分.重复访问所有句柄,然后返回原始调用所有句柄和实际超时.
iocp解决了所有这些问题,并且还引入了一个更通用的事件通知接口,这非常好.
使用iocp(以及asio):
我不确定你async_read在自定义句柄上使用的假设.你可能要测试一下.如果你的句柄指的是套接字,我想它会起作用.
至于线程问题; 是.如果您run()在io_service多个线程,事件被分派到一个免费的线程,将与更多的线程扩展.这是iocp的一个特性,它甚至还有一个线程池API.
简而言之:我相信asio或iocp可以提供比简单使用更好的性能WaitForMultipleObjects,但是这种性能是否会让你受益主要取决于你拥有多少手柄以及它们的活跃程度.