2012-08-06 53 views
1

我的主線程創建多個I/O工作線程。然後我做啓動從我的主線程的I/O請求:在我的I/O工作線程將調用線程置於可警告等待狀態

{ 
    ... 
    IoRequest *pIoRequest = new IoRequest(m_socket); 
    pIoRequest->SetBuffer(vecCommandData); // vector of BYTEs 
    pIoRequest->SetOperationType(OP_TYPE_SEND); 
    WSASend(m_socket, pIoRequest->GetWsaBuffer(), 1, NULL, 0, pIoRequest, NULL); 
    ... 
} 

在某一點上,該請求已完成,我IoRequest對象的緩衝區充滿了有效的響應數據。

DWORD WINAPI WorkerThreadProc(LPVOID lpParameter) 
{ 
    IoCompletionPort *pIocp = reinterpret_cast<IoCompletionPort*>(lpParameter);  
    ... 
    while (true) 
    { 
     BOOL bReturn = pIocp->GetStatus(&ulCompletionKey, &dwNumberOfBytesTransferred, (LPOVERLAPPED*)&pIoRequest); 
     ... 
     switch (pIoRequest->GetOperationType()) 
     { 
     ... 
     case OP_TYPE_RECEIVE_DATA: 
      { 
       ... 
       // the requested I/O operation has completed and pIoRequest's buffer now contains valid response data! 
       break; 
      } 
     ... 
     } 
    } 

    return 0; 
} 

我怎樣才能把我的主線程處於警惕性的等待狀態調用WSASend(後),並使其接收響應數據時,它準備好了?

+0

您的主線程還存在其他什麼限制(例如,您是否需要在等待時泵送消息,是否可以阻止,直到工人準備就緒等)? – 2012-08-06 12:07:30

+0

@Nate Kohl-這是我希望我的主線程工作的方式;如果已經有一個I/O請求正在處理,那麼我的主線程只是將任何進一步的請求放入一個隊列(而不是被阻塞)。無論何時當前的請求正在完成,我的主線程將一個掛起的請求出隊並使用WSASend()發送它。作爲測試,我打電話while(1){Sleep(1000); }現在WSASend()立即返回。 – jpen 2012-08-06 13:37:21

回答

2

在IOCP服務器中,通常是GetQueuedCompletionStatus()。

+1

如果您不使用IOCP,請使用[SleepEx](http://msdn.microsoft.com/en-us/library/windows/desktop/ms686307%28v=vs.85%29.aspx)。 – 2012-08-06 12:24:54

+0

@Martin James - 我正在創建一個使用IOCP的客戶端應用程序。我的GetStatus()函數內部調用GetQueuedCompletionStatus()。我所有的工作線程都通過調用這個函數來等待完成端口。我所追求的是一種機制,它允許我的主線程在I/O工作線程完成請求時得到通知。也許像在我的主線程中實現的回調函數(OnResponseDataReceived()或其他)在每個I/O請求完成時被調用? ...但我不知道該怎麼做。 – jpen 2012-08-06 13:17:08

+0

@jpen - 爲下一次數據加載發出另一個WSArecv(),然後向主線程發送PostMessage()RxBuffer(或任何您稱之爲表示WSArecv()調用及其數據的實例)實例。如果RxBuffer類包含對套接字對象的引用(它肯定必須這樣做),那麼當IOCP工作線程使用主線程消息處理程序時,如果要訪問套接字數據,則必須採取通常的預防措施。 – 2012-08-06 13:58:25