Win32 重叠 I/O - 完成例程还是 WaitForMultipleObjects? [英] Win32 Overlapped I/O - Completion routines or WaitForMultipleObjects?

查看:21
本文介绍了Win32 重叠 I/O - 完成例程还是 WaitForMultipleObjects?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道哪种方法更快,为什么?

I'm wondering which approach is faster and why ?

在编写 Win32 服务器时,我已经阅读了很多关于完成端口和重叠 I/O 的内容,但我没有阅读任何内容来建议哪组 API 在服务器中产生最佳结果.

While writing a Win32 server I have read a lot about the Completion Ports and the Overlapped I/O, but I have not read anything to suggest which set of API's yields the best results in the server.

我应该使用完成例程,还是应该使用 WaitForMultipleObjects API,为什么?

Should I use completion routines, or should I use the WaitForMultipleObjects API and why ?

推荐答案

您建议了两种执行重叠 I/O 的方法,而忽略第三种方法(或者我误解了您的问题).

You suggest two methods of doing overlapped I/O and ignore the third (or I'm misunderstanding your question).

当您发出重叠操作时,WSARecv() 例如,您可以指定一个包含事件的 OVERLAPPED 结构,您可以等待该事件发出信号以指示重叠 I/O 已完成.我假设这是您的 WaitForMultipleObjects() 方法,并且如前所述,这不能很好地扩展,因为您受限于可以传递给 WaitForMultipleObjects() 的句柄数量.

When you issue an overlapped operation, a WSARecv() for example, you can specify an OVERLAPPED structure which contains an event and you can wait for that event to be signalled to indicate the overlapped I/O has completed. This, I assume, is your WaitForMultipleObjects() approach and, as previously mentioned, this doesn't scale well as you're limited to the number of handles that you can pass to WaitForMultipleObjects().

或者,您可以传递一个完成例程,该例程在完成发生时被调用.这称为alertable I/O",要求发出 WSARecv() 调用的线程处于alertable"状态,以便调用完成例程.线程可以通过多种方式(调用 SleepEx() 或各种 EX 版本的 Wait 函数等)将自身置于警报状态.我打开的 Richter book在我面前说我已经与可警报 I/O 打交道了很多,我会第一个告诉你,可警报 I/O 是可怕的,应该避免".恕我直言,说够了.

Alternatively you can pass a completion routine which is called when completion occurs. This is known as 'alertable I/O' and requires that the thread that issued the WSARecv() call is in an 'alertable' state for the completion routine to be called. Threads can put themselves in an alertable state in several ways (calling SleepEx() or the various EX versions of the Wait functions, etc). The Richter book that I have open in front of me says "I have worked with alertable I/O quite a bit, and I'll be the first to tell you that alertable I/O is horrible and should be avoided". Enough said IMHO.

还有第三种方法,在发出调用之前,您应该将要进行重叠 I/O 的句柄与完成端口相关联.然后创建一个线程池,通过调用 GetQueuedCompletionStatus() 和循环来为这个完成端口提供服务.您使用 OVERLAPPED 结构发出 WSARecv(),其中没有事件,当 I/O 完成时,完成会从您的一个 I/O 池线程上的 GetQueuedCompletionStatus() 弹出,并可以在那里处理.

There's a third way, before issuing the call you should associate the handle that you want to do overlapped I/O on with a completion port. You then create a pool of threads which service this completion port by calling GetQueuedCompletionStatus() and looping. You issue your WSARecv() with an OVERLAPPED structure WITHOUT an event in it and when the I/O completes the completion pops out of GetQueuedCompletionStatus() on one of your I/O pool threads and can be handled there.

如前所述,Vista/Server 2008 稍微清理了 IOCP 的工作方式,并消除了您必须确保发出重叠请求的线程继续运行直到请求完成的问题.这里.但无论如何,这个问题很容易解决;您只需使用用于完成的相同 IOCP 将 WSARecv 编组到您的 I/O 池线程之一......

As previously mentioned, Vista/Server 2008 have cleaned up how IOCPs work a little and removed the problem whereby you had to make sure that the thread that issued the overlapped request continued to run until the request completed. Link to a reference to that can be found here. But this problem is easy to work around anyway; you simply marshal the WSARecv over to one of your I/O pool threads using the same IOCP that you use for completions...

无论如何,恕我直言,使用 IOCP 是进行重叠 I/O 的最佳方式.是的,一开始就了解调用的重叠/异步性质可能需要一些时间,但这是非常值得的,因为系统可扩展性非常好,并提供了一种简单的即发即弃"方法来处理重叠操作.

Anyway, IMHO using IOCPs is the best way to do overlapped I/O. Yes, getting your head around the overlapped/async nature of the calls can take a little time at the start but it's well worth it as the system scales very well and offers a simple "fire and forget" method of dealing with overlapped operations.

如果您需要一些示例代码来帮助您前进,那么我有几篇关于编写 IO 完成端口系统的文章和一堆为高性能服务器提供真实框架的免费代码;请参阅此处.

If you need some sample code to get you going then I have several articles on writing IO completion port systems and a heap of free code that provides a real-world framework for high performance servers; see here.

顺便说一句;恕我直言,你真的应该阅读Windows Via C/C++ (PRO-Developer)" 由 Jeffrey Richter 和 Christophe Nasarre 撰写,因为它提供了您需要了解的有关重叠 I/O 和大多数其他信息的所有信息先进的 Windows 平台技术和 API.

As an aside; IMHO, you really should read "Windows Via C/C++ (PRO-Developer)" by Jeffrey Richter and Christophe Nasarre as it deals will all you need to know about overlapped I/O and most other advanced windows platform techniques and APIs.

这篇关于Win32 重叠 I/O - 完成例程还是 WaitForMultipleObjects?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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