创建子进程时,保存标准输出管道的写入结束句柄。然后你可以写一个字符来解锁已经调用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