gpt4 book ai didi

c++ - WaitForMultipleObjects 和 boost::asio 在多个 windows::basic_handle 上有什么区别?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:05:50 27 4
gpt4 key购买 nike

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

  1. 在所有这些句柄上调用 WaitForMultipleObjects
  2. async_read on boost::windows::basic_handle's around all these handles

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

最佳答案

因为它听起来像是您从 asio 派生的主要用途,所以它构建在 IO 完成端口(简称 iocp)之上。因此,让我们开始比较 iocp 和 WaitForMultipleObjects()。这两种方法在本质上与 linux 上的 selectepoll 相同。

iocp 解决的 WaitForMultipleObjects 的主要缺点是无法使用许多文件描述符进行扩展。它是 O(n),因为对于您收到的每个事件,您再次传入完整数组,并且内部 WaitForMultipleObjects 必须扫描数组以了解触发哪个句柄。

但是,由于第二个缺点,这很少成为问题。 WaitForMultipleObjects() 对其可以等待的最大句柄数有限制 (MAXIMUM_WAIT_OBJECTS)。此限制为 64 个对象(请参阅 winnt.h)。通过创建 Event 对象并将多个套接字绑定(bind)到每个事件,然后等待 64 个事件,可以绕过此限制。

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

这意味着,如果您正在等待 10 个非常活跃的套接字,并且大多数时候所有这些套接字上都有一个事件,那么将非常偏向于为传递给 的列表中的第一个套接字提供服务等待多个对象。这可以通过以下方式规避,每次函数返回并且事件已被服务时,再次运行它,超时为 0,但这次只传递数组 1 中触发事件的部分。重复直到访问了所有句柄,然后返回到具有所有句柄和实际超时的原始调用。

iocp 解决了所有这些问题,还引入了一个更通用的事件通知接口(interface),非常好。

使用 iocp(以及因此使用 asio):

  1. 您无需重复您感兴趣的句柄,只需告诉 Windows 一次,它就会记住。这意味着它可以更好地扩展许多句柄。
  2. 您没有可以等待的句柄数量限制
  3. 您获得每个事件,即没有偏向任何特定句柄

我不确定您对自定义句柄使用 async_read 的假设。你可能需要测试一下。如果您的句柄指的是套接字,我想它会起作用。

至于线程问题;是的。如果您在多个线程中run() io_service,事件将被分派(dispatch)到一个空闲线程,并将随着更多线程的扩展而扩展。这是 iocp 的一个特性,它甚至有一个线程池 API。

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

关于c++ - WaitForMultipleObjects 和 boost::asio 在多个 windows::basic_handle 上有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6201759/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com