2016-09-20 99 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。