Winapi 取消管道的IO
我正在使用CreatePipe将stdin/out从进程重定向到我的进程 到目前为止效果还不错。问题是当我想要终止等待客户机进程写入内容的线程时 我可以使用CancelIoEx,但这只适用于Vista+,我还需要一个XP解决方案。如果没有CancelIoEx,另一个线程中的ReadFile将永远不会返回 我也不能使用重叠的ReadFile,因为使用CreatePipe创建的管道不支持它Winapi 取消管道的IO,winapi,pipe,Winapi,Pipe,我正在使用CreatePipe将stdin/out从进程重定向到我的进程 到目前为止效果还不错。问题是当我想要终止等待客户机进程写入内容的线程时 我可以使用CancelIoEx,但这只适用于Vista+,我还需要一个XP解决方案。如果没有CancelIoEx,另一个线程中的ReadFile将永远不会返回 我也不能使用重叠的ReadFile,因为使用CreatePipe创建的管道不支持它 有任何选项吗?在创建子进程时,将句柄保存到标准输出管道的写入端。然后,您可以向该线程写入一个字符,以解除对调用
有任何选项吗?在创建子进程时,将句柄保存到标准输出管道的写入端。然后,您可以向该线程写入一个字符,以解除对调用ReadFile的线程的阻止,该线程正在从标准输出管道的读取端进行读取。为了不将其解释为数据,请创建一个Event CreateEvent,该事件在写入伪字符的线程中设置为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将失败。@Hanpassant如果不关闭,请关闭句柄块。请改用CreateNamedPipe,然后可以使用重叠I/O。请参阅