2013-02-14 29 views
0

我正在使用I/O完成端口進程管理庫(是的,這是有原因的)。你可以在這裏找到我在說的東西的來源:https://github.com/jcommon/process/blob/master/src/main/java/jcommon/process/platform/win32/Win32ProcessLauncher.java(看看第559行和第1137行 - 是的,這個類需要重構和清理)。I/O完成端口和stdout處理

爲了處理子進程的stdout和stderr,我正在啓動子進程並使用命名管道(不是匿名管道b/c我需要異步,重疊的ReadFile()/ WriteFile())。這主要是實際工作。在一項測試中,我啓動了1,000個併發進程並監視它們的輸出,確保它們發出正確的信息。通常情況下,所有1,000人工作正常或998人,留下一對有問題的夫婦。

這幾對進程顯示並非所有的消息都被接收到。我知道該消息正在輸出,但該進程的線程處理GetQueuedCompletionStatus()從ERROR_BROKEN_PIPE讀取返回。

預期的行爲是操作系統(或C庫)會在進程退出時刷新標準輸出緩衝區上的剩餘字節。然後,我會希望這些字節排隊到我的iocp之前得到一個壞的管道錯誤。相反,這些字節看起來消失了,並且讀取完成了一個ERROR_BROKEN_PIPE--在我的代碼中,這會導致它啓動子進程的拆卸。

我寫了一個簡單的應用程序來測試並找出行爲(https://github.com/jcommon/process/blob/master/src/test/c/stdout-1.c)。此應用程序禁用標準輸出緩衝,因此所有寫入操作應立即刷新。在我的測試中使用該程序會產生與啓動「cmd.exe/c echo hi」相同的問題。無論如何,當進程退出時,應用程序(或OS?)不應該在stdout中刷新剩餘的字節嗎?

該源代碼是使用直接映射JNA的Java,但對於C/C++工程師來說應該相當容易。

感謝您提供任何幫助!

回答

0

是否確定在非零ioSize中沒有發生管道故障錯誤?如果ioSize不爲零,則應該處理讀取的數據以及注意該文件現在已關閉。

我的C++代碼基本上忽略了ERROR_BROKEN_PIPEERROR_HANDLE_EOF,只是等待下一次讀取嘗試失敗,出現上述錯誤之一或者當前讀取完成時讀取零字節。有問題的代碼適用於文件和管道,我從來沒有看到您在運行您描述的那種測試時所描述的問題。