2016-09-20 104 views
1

今天笔者了解到,我可以打电话CreateIoCompletionPort(),然后通过返回HANDLEWaitForSingleObject()完成端口上的WaitForSingleObject()?

#include <Windows.h> 

int main() 
{ 
    HANDLE h = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0); 
    auto bRes = PostQueuedCompletionStatus(h, 1, 2, 0); 
    if (!bRes) { 
     abort(); 
    } 

    auto dwRes = WaitForSingleObject(h, INFINITE); 
    if (dwRes != WAIT_OBJECT_0){ 
     abort(); 
    } 

    LPOVERLAPPED pOvr; 
    DWORD cb; 
    ULONG_PTR key; 
    bRes = GetQueuedCompletionStatus(
     h, &cb, &key, &pOvr, INFINITE); // <-- returns 1, 2, nullptr 

    if (!bRes) { 
     abort(); 
    } 

    dwRes = WaitForSingleObject(h, INFINITE); // <-- blocks here 
    return 0; 
} 

它工作在我的Windows 10盒预期。

这样的行为是已知的还是合法的或有记录的?我无法找到任何有关它的信息。

+0

'dwRes = WaitForSingleObject(h,INFINITE); // < - 块在这里 - 真的阻止?你确定 ?只是想知道 – RbMm

+0

是的。在等待状态和源代码崩溃转储在这里:https://1drv.ms/f/s!AtyOp6RRifUTuC2CAVzWdFrvZu6w –

+0

是的,在win10真的等待KQUEUE调度头。但在win8.1中说 - 不。 – RbMm

回答

3

如果你读了WaitForSingleObject() documentation,一个I/O完成端口是允许的手柄类型:

WaitForSingleObject功能可以等待以下对象:

  • 更改通知
  • 控制台输入
  • 事件
  • 内存资源通知
  • 互斥
  • 过程
  • 信号灯
  • 螺纹
  • 可等待计时器

等待完成事件的端口上到达,你必须通过手柄到GetQueuedCompletionStatus()本身,并让它阻塞,直到事件到达或超时发生。

#include <Windows.h> 

int main() 
{ 
    HANDLE h = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0); 
    auto bRes = PostQueuedCompletionStatus(h, 1, 2, 0); 
    if (!bRes) { 
     abort(); 
    } 

    LPOVERLAPPED pOvr; 
    DWORD cb; 
    ULONG_PTR key; 
    bRes = GetQueuedCompletionStatus(
     h, &cb, &key, &pOvr, INFINITE); // <-- returns 1, 2, nullptr 

    if (!bRes) { 
     abort(); 
    } 

    bRes = GetQueuedCompletionStatus(
     h, &cb, &key, &pOvr, INFINITE); // <-- blocks here 

    return 0; 
} 
+1

感谢您的及时响应:-) WaitForSingleObject()可以等待文件句柄,虽然在WaitForSingleObject()的文档中没有明确提到它(请参阅https://blogs.msdn.microsoft.com/oldnewthing/20121012-00/?p=6343,“一个文件句柄是一个可等待的对象“)。 我完全知道正确使用完成端口。我想知道一个竣工港是否也是一个等待的对象。 –

+0

['GetOverlappedResult()'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683209.aspx)的文档提到一个文件,命名管道和通信设备句柄也是可以处理,但不鼓励直接等待。但[I/O完成端口文档](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198.aspx)中没有提到I/O完成端口句柄直接等待。如果没有记录,请不要依赖它。 –

1

摘要:

  • 不这样做。请参阅Remy Lebeau的答案和MSDN,了解如何正确使用完成端口。
  • 这样滥用完井港不仅没有证件,而且也不可靠。行为因Windows 10的版本而异。
  • 完成端口可能是内核中等待的合法对象,因为支持完成端口的KQUEUE具有DISPATCHER_HEADER。