2010-07-11 71 views
1

我一直在做大量的搜索,仍然似乎無法弄清楚如何解決我的問題。我正在編寫一個GUI程序(在WinAPI中,所以不需要MFC)與另一個程序(基於命令行)進行通信。我使用匿名管道,因爲一切都是本地的(但也許命名管道會更好?),然後我使用CreateProcess();運行我試圖從中獲取輸出的程序。幫助異步I/O

現在,我剛剛從幾小時前的同步轉移到異步,並且遇到了一些問題(即使同步沒有做我想要的東西)。第一個問題是我在運行同步I/O時仍遇到同樣的問題;如果我運行我的「讀取」(或「寫入」)功能不止一次,程序將凍結。我不能這樣做,因爲程序的目的是定期更新GUI到命令提示符的輸出。

第二個問題,最終更嚴重的是一個新的異步I/O;它不像我的同步一樣讀取整個輸出。它讀取,直到我正在閱讀的程序發送返回字符(否則,它恰好是巧合,這是它停止閱讀的點)。我覺得我可能不完全理解OVERLAP的功能,但是現在我正在閱讀如此多的MSDN,因此我可能忽略了一些重要的方面。

所以基本上,下面的代碼是我正在做的最低限度。我曾嘗試使用各種for()和while()循環技術來嘗試獲取所有輸出數據,但它似乎是不行的。請注意,BUFSIZE定義在0x1000,這實際上比我爲這個需求編寫的小測試程序還要多。

::ReadFile(_hChild_Out_Rd, chBuf, BUFSIZE, &dwRead, &o1); 
chBuf[dwRead] = '\0'; 
::SetDlgItemTextA(global,IDO_WORLDOUT,chBuf); 

那麼,有沒有人有任何想法?

非常感謝您的幫助!

問候,
丹尼斯M.

回答

2

這看起來像同步代碼。使用異步(OVERLAPPED)I/O時,只有操作完成後才能使用緩衝區。設置OVERLAPPED結構的hEvent成員,並將主循環從PeekMessage更改爲MsgWaitForMultipleObjects,以便您的程序可以響應I/O事件。然後,您可以等待OVERLAPPED操作手柄以及進程句柄,以便知道何時退出其他程序。

+0

我現在唯一的問題是如何將流程寫入命名管道?我創建了一個名稱管道,並嘗試以與匿名管道相同的方式運行一個進程,但無法訪問輸出。有任何想法嗎? – RageD 2010-07-11 06:16:00

+0

匿名教皇應該爲此目的而工作得很好,但是如果您想使用命名管道,請注意您必須單獨打開兩端(並且兩端都是雙向的),不像匿名情況下您得到一對手柄通過單個API調用到單向管道的末端。 – 2010-07-11 11:56:31

+0

執行'CreatePipe()'返回的文件句柄,甚至是否設置了'FILE_FLAG_OVERLAPPED'? 'CreatePipe()'沒有「文件模式」或「打開模式」參數。 – bk1e 2010-07-11 16:28:52

0

您可能希望查看內存映射文件,您可以在內存中構建一個隊列,並從一個地方寫入並從另一個地方讀取。在一個項目中,我做了一個循環隊列,其中一個進程寫入隊列,另一個進程在有時間的時候讀取。

您可以創建一個內存映射文件是這樣的:

SECURITY_ATTRIBUTES sa; 
sa.bInheritHandle = TRUE; 
sa.nLength = sizeof(sa); 
sa.lpSecurityDescriptor = NULL; 

hdFile = CreateFileMapping(INVALID_HANDLE_VALUE,&sa, 
    PAGE_READWRITE,0,dwBufSize, L"SomeName"); 

然後你得到一個指針到共享內存這樣

pOutSharedMemory=MapViewOfFile(hdFile,FILE_MAP_ALL_ACCESS,0,0,dwBufSize); 

現在你可以指向映射到內存

例如一對夫婦計數器來跟蹤你在(內dwBufSize)

pdwReadOffset = reinterpret_cast<DWORD*>(pOutSharedMemory) 
pdwWriteOffset = pdwReadOffset + sizeof(DWORD) 

內存中的,然後有一些結構,你再使用的memmove

讀/寫的內存,你必須照顧使用關鍵部分的同步等。

+0

你真的需要使用管道,我不知道有什麼方法將'STARTUPINFO'的'hStdOutput'成員設置爲內存映射區域,子進程也不知道如何將訪問同步到循環緩衝區。 http://msdn.microsoft.com/en-us/library/ms686331(v=VS.85).aspx – 2010-07-11 01:35:39

+0

由於有不同的讀寫計數器和互斥量應該足以同步它們,但我同意命名管道可能是OPs情況最好的,只是提出了幾年前我已經使用的替代方案。 – 2010-07-11 02:06:51