19 io winapi crystal-reports io-completion-ports
我想知道哪种方法更快,为什么?
在编写Win32服务器的过程中,我已经阅读了很多有关完成端口和重叠I/O的内容,但是我没有读过任何内容来暗示哪一组API在服务器中产生最佳结果.
我应该使用完成例程,还是应该使用WaitForMultipleObjects API?为什么?
Len*_*ate 34
您建议两种方法进行重叠I/O并忽略第三种方法(或者我误解了您的问题).
例如,当您发出重叠操作(例如WSARecv())时,您可以指定包含事件的OVERLAPPED结构,并且可以等待该事件发出信号以指示重叠的I/O已完成.我假设这是您的WaitForMultipleObjects()方法,并且如前所述,由于您可以将传递给WaitForMultipleObjects()的句柄数量限制,因此这不能很好地扩展.
或者,您可以传递完成例程,该例程在完成时调用.这称为"可警告I/O",并要求发出WSARecv()调用的线程处于"可警告"状态,以便调用完成例程.线程可以通过多种方式将自己置于可警告状态(调用SleepEx()或等待函数的各种EX版本等).我在我面前打开的里希特书中写道:"我已经开始使用可警告的I/O了,我会第一个告诉你,可警告的I/O很糟糕,应该避免".恕我直言.
还有第三种方法,在发出调用之前,您应该将要执行重叠I/O的句柄与完成端口相关联.然后,您可以通过调用GetQueuedCompletionStatus()并循环来创建一个服务此完成端口的线程池.使用OVERLAPPED结构发出WSARecv(),其中没有事件,当I/O完成完成时,会在其中一个I/O池线程上弹出GetQueuedCompletionStatus(),并且可以在那里处理.
如前所述,Vista/Server 2008已经清理了IOCP如何工作一点并解决了问题,因此您必须确保发出重叠请求的线程继续运行直到请求完成.可以在此处找到对该引用的链接.但无论如何这个问题很容易解决; 您只需使用与完成时使用的相同IOCP将WSARecv封送到您的一个I/O池线程中...
无论如何,使用IOCP的IMHO是进行重叠I/O的最佳方式.是的,了解调用的重叠/异步性质可能会在开始时花费一些时间,但它非常值得,因为系统可以很好地扩展并提供一种处理重叠操作的简单"即发即忘"方法.
如果您需要一些示例代码来帮助您,那么我有几篇关于编写IO完成端口系统和一堆免费代码的文章,这些代码为高性能服务器提供了真实的框架.看到这里.
作为旁白; 恕我直言,你真的应该阅读Jeffrey Richter和Christophe Nasarre撰写的" Windows Via C/C++(PRO-Developer) ",因为它可以让您了解重叠I/O和大多数其他高级Windows平台技术和API.
" 网络编程for Microsoft Windows"第2版中的表6-3 比较了通过完成端口与其他技术重叠I/O的可扩展性.完成端口在吞吐量方面将所有其他I/O模型从水中吹走,同时使用更少的线程.
| 归档时间: |
|
| 查看次数: |
13176 次 |
| 最近记录: |