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

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

问题描述

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



在编写Win32服务器时,我已经阅读了很多关于完成端口和重叠I /但我没有读任何建议哪些API的产量在服务器中最好的结果。



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

解决方案

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



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



或者,您可以传递一个完成例程,在完成时调用该例程。这被称为可警告的I / O,并且要求发出WSARecv()调用的线程处于可警告状态,以便调用完成例程。线程可以通过几种方式(调用SleepEx()或各种EX版本的Wait函数等)将自己置于可警告状态。我有里希特书在我面前打开说:我已经与可靠的I / O工作了很多,我会第一个告诉你,可警告的I / O是可怕的,应该避免。够了IMHO。



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



如前所述,Vista / Server 2008已经清理了IOCP的工作方式,并删除了一个问题,你必须确保发出重叠请求的线程继续运行,直到请求完成。您可以在此处找到其引用的链接。但这个问题很容易工作;你只需将WSARecv编组到你的I / O池线程之一,使用与完成相同的IOCP ...

无论如何,使用IOCP的IMHO是最好的方式做重叠I / O。是的,让你的头部围绕重叠/异步性质的调用可能需要一些时间开始,但它是非常值得的,因为系统缩放非常好,并提供了一个简单的火和忘记的方法来处理重叠操作。 / p>

如果你需要一些示例代码让你走,那么我有几篇关于编写IO完成端口系统的文章和一堆自由代码,为高层提供了一个真实的框架性能服务器;请参阅此处



另外, IMHO,您应该阅读 Windows通过C / C ++(PRO-Developer)作者Jeffrey Richter和Christophe Nasarre的所有你需要知道的重叠I / O和大多数其他高级Windows平台技术和API。


I'm wondering which approach is faster and why ?

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.

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

解决方案

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

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

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.

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.

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...

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.

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.

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天全站免登陆