簡體   English   中英

如何正確啟動進程並轉發stdin / stdout / stderr?

[英]How do I correctly launch a process and forward stdin/stdout/stderr?

我正在使用CreateProcess啟動交互式腳本解釋器,並希望透明地從解釋器轉發stdin / stdout / stderr。

我的第一次嘗試是設置傳遞給CreateProcessSTARTUPINFO結構,例如

STARTUPINFOA si = { sizeof( si ) };
si.hStdError = ::GetStdHandle( STD_ERROR_HANDLE );
si.hStdOutput = ::GetStdHandle( STD_OUTPUT_HANDLE );
si.hStdInput = ::GetStdHandle( STD_INPUT_HANDLE );
si.dwFlags |= STARTF_USESTDHANDLES;

即,我試圖使腳本解釋器進程使用與啟動器進程相同的句柄進行讀寫。 但這似乎沒有用(我什至不確定那些標准句柄是否可以繼承)。

基於創建帶有重定向的輸入和輸出的子進程示例的第二個想法是設置三個管道以轉發所有寫入任何管道的數據。 由於我不知道如何等待將數據寫入多個文件( WaitForMultipleObjects無法在管道上同步),因此我考慮使用三個線程,每個線程在管道上執行阻塞性ReadFile調用。

我懷疑這可能會矯kill過正,所以我想知道:有沒有更簡單的方法可以做到這一點? 我根本不需要對從/從腳本解釋器傳遞的數據進行任何形式的處理。

附帶說明一下,在Linux上,我使用execvp只是用腳本解釋器進程替換了當前進程,但是在Windows上,我需要在主線程處於掛起狀態的情況下啟動腳本解釋器(以便我可以進行一些字節碼修補) )-因此即使_execvp在Windows上似乎可用,我顯然也必須使用CreateProcess。

為了等待多個文件或管道上的I / O,您對每個文件發出異步I / O請求,然后等待所述請求完成。 遵循以下原則(未經測試):

HANDLE file1, file2; // initialized somehow

HANDLE events[2];
events[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
events[1] = CreateEvent(NULL, TRUE, FALSE, NULL);

OVERLAPPED overlapped1 = {0};
overlapped1.hEvent = events[0];
OVERLAPPED overlapped2 = {0};
overlapped2.hEvent = events[1];

ReadFile(file1, buffer1, size1, NULL, &overlapped1);
ReadFile(file2, buffer2, size2, NULL, &overlapped2);

WaitForMultipleObjects(2, events, FALSE, INFINITE);

ReadFileWaitForMultipleObjects將需要在循環中調用。 您檢查WaitForMultipleObjects的返回值以了解哪個操作已完成,使用GetOverlappedResult查找該操作的結果(是否成功,以及是否成功,檢索到了多少個字節),處理數據,並在以下情況下再次調用ReadFile進行處理:您想從中了解更多信息,然后回到等待狀態。 這有點類似於Linux中select驅動的非阻塞I / O循環。

I / O完成端口是更高級的技術。 這使一個線程池可以處理大量異步I / O。 通常用於Web服務器等,可能對您的情況有些大材小用。

如果確保不要在CreateProcessdwFlags參數中傳遞CREATE_NO_WINDOW參數,則按OP所示彈出STARTUPINFO效果很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM