創建子進程時,保存標準輸出管道的寫入結束句柄。然後你可以寫一個字符來解鎖已經調用ReadFile的線程(即從標準輸出管道的讀取端讀取)。爲了不將其解釋爲數據,請在寫入虛擬字符的線程中創建一個設置爲(SetEvent)的Event(CreateEvent),並在ReadFile返回後進行檢查。有點混亂,但似乎工作。
/* Init */
stdout_closed_event = CreateEvent(NULL, TRUE, FALSE, NULL);
/* Read thread */
read_result = ReadFile(stdout_read, data, buf_len, &bytes_read, NULL);
if (!read_result)
ret = -1;
else
ret = bytes_read;
if ((bytes_read > 0) && (WAIT_OBJECT_0 == WaitForSingleObject(stdout_closed_event, 0))) {
if (data[bytes_read-1] == eot) {
if (bytes_read > 1) {
/* Discard eot character, but return the rest of the read data that should be valid. */
ret--;
} else {
/* No data. */
ret = -1;
}
}
}
/* Cancel thread */
HMODULE mod = LoadLibrary (L"Kernel32.dll");
BOOL WINAPI (*cancel_io_ex) (HANDLE, LPOVERLAPPED) = NULL;
if (mod != NULL) {
cancel_io_ex = (BOOL WINAPI (*) (HANDLE, LPOVERLAPPED)) GetProcAddress (mod, "CancelIoEx");
}
if (cancel_io_ex != NULL) {
cancel_io_ex(stdout_write_pipe, NULL);
} else {
SetEvent(stdout_closed_event);
WriteFile(stdout_write_pipe, &eot, 1, &written, NULL);
}
只需關閉管道,ReadFile()就會失敗。 – 2014-11-23 14:14:38
@HansPassant它不,CloseHandle()塊。 – Michael 2014-11-23 14:16:20
改爲使用CreateNamedPipe,然後您可以使用重疊的I/O。 – 2014-11-23 23:23:03