2010-10-31 30 views
2
while(GetExitCodeProcess(processInfo.hProcess, &exitCode) 
     && exitCode == STILL_ACTIVE) 
{ 
    ReadFile(defaultSTDIN, chBuf, 1, &dwRead, 0); 
    WriteFile(writingEnd, chBuf, 1, &dwWritten, 0); 
} 

上述代碼的問題是,即使當通過processInfo.hProcess引用的子進程退出時,我們仍然停留在while循環中,因爲ReadFile()正在等待輸入。什麼是解決這個問題的最好方法?可能在ReadFile()上有超時?

回答

7

您需要的是在打開文件時使用FILE_FLAG_OVERLAPPED標誌異步讀取文件,並指定ReadFile函數的OVERLAPPED結構。然後,您可以等待讀取操作和進程終止,並採取適當的行動。

+0

同意。附:我很長一段時間都在使用重疊I/O。真正缺少的是異步模式下的所有其他文件操作:打開文件,調用'SetEndOfFile'等。 – valdo 2010-10-31 12:43:17

+3

+1你介意給出一個例子嗎? – aCuria 2010-11-18 09:37:07

5

可以假設一個非重疊ReadFile超時,但間接。

首先,您必須使用SetCommTimeouts來設置句柄的超時時間,具體而言,必須至少有一個值設置爲傳遞給此函數的ReadTotalTimeoutConstant。 (一個警告:當你的句柄指向一個通信端口時,這個函數可以工作,但如果這個文件實際上是一個正在被讀取的文件,它不知道它是如何工作的。)ReadFile函數在完成時會啓動填充其緩衝區,到達文件結尾,或達到超時時間。它不會拋出任何錯誤或任何東西,以確定超時發生,你需要比較你的& dwRead到期望的字節數。因爲你只是在尋找1個字節,所以你有一個超時,而不是文件結束。

所以這樣我會寫(我不能說我下面的最佳做法或任何東西)是做到以下幾點:

COMMTIMEOUTS timeouts = { 0, //interval timeout. 0 = not used 
           0, // read multiplier 
          10, // read constant (milliseconds) 
           0, // Write multiplier 
           0 // Write Constant 
          }; 


    SetCommTimeouts(defaultSTDIN, &timeouts); 

    while(GetExitCodeProcess(processInfo.hProcess, &exitCode) 
      && exitCode == STILL_ACTIVE) 
    { 
     ReadFile(defaultSTDIN, chBuf, 1, &dwRead, 0); 
     if (dwRead == 0) { 
        //insert code to handle timeout here 
     } 
     WriteFile(writingEnd, chBuf, 1, &dwWritten, 0); 
    } 
+0

沒有工作在NamedPipe – serup 2017-06-27 10:49:33

+0

有用的知識。它可能只適用於COM端口,因爲CreateFile的其他用途可能不會實現COMMTIMEOUTS。 – 2017-07-24 18:10:52