[英]win32: how stop ReadFile (stdin|pipe)
我有通過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
}
其中timeToExit
是std::atomic<bool>
。
我想從另一個線程停止該線程。 我嘗試了這個:
timeToExit = true;
CloseHandle(stdinHandle);
並且代碼掛在CloseHandle
。
當程序正在運行的其他程序使用CreatePipe
和DuplicateHandle
將我的程序輸入重定向到管道時,代碼將掛起。
那么,我該如何以win32方式停止while (!timeToExit)..
線程? 還是我應該while (!timeToExit)..
線程中進行一些更改以使其停止?
更新我在以stdin和event作為參數調用ReadFile
之前考慮了WaitForMultipleObjects
用法,並在其他線程中觸發事件,但是沒有提到匿名管道作為WaitForMultipleObjects
可能輸入,加上我在stdin連接到控制台時嘗試過,在第一個字符輸入到控制台后變得無用(總是無延遲地返回控制),在這種情況下,我不得不使用ReadConsoleInput
而不是ReadFile
?
從控制台的實際STDIN讀取時,可以使用PeekConsoleInput()
和ReadConsoleInfo()
代替ReadFile()
。
從(未)命名管道讀取時,請在調用ReadFile()
之前使用PeekNamedPipe()
ReadFile()
。
這將允許您在實際讀取STDIN之前輪詢STDIN是否有新輸入,然后可以在兩次輪詢之間檢查線程終止狀態。
您可以使用GetFileType()
來檢測將哪種設備連接到STD_INPUT_HANDLE
句柄。
最簡單的解決方案是使用CancelSynchronousIo
。
最安全的方法是使用OVERLAPPED結構等異步調用(非阻塞) ReadFile 。這可以從您的主線程完成。
如果/當您需要取消它時,請調用CancelIo (從與ReadFile相同的線程)或CancelIoEx (如果從另一個線程)。
您也許可以使當前的方法起作用; 如果將timeToExit標記為volatile,它可能不會掛起,但是這種方法通常會帶來更大的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.