자식 프로세스를 생성 할 때 stdout 파이프의 쓰기 엔드에 핸들을 저장하십시오. 그런 다음 문자를 써서 ReadFile (stdout 파이프의 읽기 끝에서 읽음)을 호출 한 스레드의 차단을 해제 할 수 있습니다. 이것을 데이터로 해석하지 않으려면 더미 문자를 쓰는 스레드에서 SetEvent (SetEvent) 이벤트를 만들고 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()이 실패합니다. –
@HansPassant, CloseHandle() 블록은 그렇지 않습니다. – Michael
대신 CreateNamedPipe를 사용하면 겹쳐진 I/O를 사용할 수 있습니다. –