[英]win32: how stop ReadFile (stdin|pipe)
I have handle that I got via stdinHandle = GetStdHandle(STD_INPUT_HANDLE)
and I have separate thread which execute such code: 我有通过
stdinHandle = GetStdHandle(STD_INPUT_HANDLE)
获得的句柄,并且我有执行该代码的单独线程:
while (!timeToExit) {
char ch;
DWORD readBytes = 0;
if (!::ReadFile(stdinHandle, &ch, sizeof(ch), &readBytes, nullptr)) {
//report error
return;
}
if (readBytes == 0)
break;
//handle new byte
}
where timeToExit
is std::atomic<bool>
. 其中
timeToExit
是std::atomic<bool>
。
I wan to stop this thread from another thread. 我想从另一个线程停止该线程。 I tried this:
我尝试了这个:
timeToExit = true;
CloseHandle(stdinHandle);
and code hangs in CloseHandle
. 并且代码挂在
CloseHandle
。
The code hangs while program is running by other program that uses CreatePipe
and DuplicateHandle
to redirect input of my program to pipe. 当程序正在运行的其他程序使用
CreatePipe
和DuplicateHandle
将我的程序输入重定向到管道时,代码将挂起。
So how should I stop while (!timeToExit)..
thread in win32 way? 那么,我该如何以win32方式停止
while (!timeToExit)..
线程? Or may be I should some how change while (!timeToExit)..
thread to make it possible to stop it? 还是我应该
while (!timeToExit)..
线程中进行一些更改以使其停止?
Update I thought about usage of WaitForMultipleObjects
before call of ReadFile
with stdin and event as arguments, and trigger event in other thread, but there is no mention of anonymous pipe as possible input for WaitForMultipleObjects
, plus I tried when stdin connected to console, and it become useless (always return control without delay) after the first character typed into console, looks like I have to use ReadConsoleInput
in this case, instead of ReadFile
? 更新我在以stdin和event作为参数调用
ReadFile
之前考虑了WaitForMultipleObjects
用法,并在其他线程中触发事件,但是没有提到匿名管道作为WaitForMultipleObjects
可能输入,加上我在stdin连接到控制台时尝试过,在第一个字符输入到控制台后变得无用(总是无延迟地返回控制),在这种情况下,我不得不使用ReadConsoleInput
而不是ReadFile
?
When reading from a console's actual STDIN, you can use PeekConsoleInput()
and ReadConsoleInfo()
instead of ReadFile()
. 从控制台的实际STDIN读取时,可以使用
PeekConsoleInput()
和ReadConsoleInfo()
代替ReadFile()
。
When reading from an (un)named pipe, use PeekNamedPipe()
before calling ReadFile()
. 从(未)命名管道读取时,请在调用
ReadFile()
之前使用PeekNamedPipe()
ReadFile()
。
This will allow you to poll STDIN for new input before actually reading it, and then you can check your thread termination status in between polls. 这将允许您在实际读取STDIN之前轮询STDIN是否有新输入,然后可以在两次轮询之间检查线程终止状态。
You can use GetFileType()
to detect what kind of device is attached to your STD_INPUT_HANDLE
handle. 您可以使用
GetFileType()
来检测将哪种设备连接到STD_INPUT_HANDLE
句柄。
最简单的解决方案是使用CancelSynchronousIo
。
The safest way to do this would be to call ReadFile asynchronously (non-blocking) using the OVERLAPPED structure etc. This can be done from your main thread. 最安全的方法是使用OVERLAPPED结构等异步调用(非阻塞) ReadFile 。这可以从您的主线程完成。
If/when you need to cancel it, call CancelIo (from same thread that called ReadFile) or CancelIoEx (if from another thread). 如果/当您需要取消它时,请调用CancelIo (从与ReadFile相同的线程)或CancelIoEx (如果从另一个线程)。
You might be able to make your current approach work; 您也许可以使当前的方法起作用; if you mark timeToExit as volatile, it may not hang, but that approach commonly creates bigger problems.
如果将timeToExit标记为volatile,它可能不会挂起,但是这种方法通常会带来更大的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.