簡體   English   中英

win32:如何停止ReadFile(stdin | pipe)

[英]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
}

其中timeToExitstd::atomic<bool>

我想從另一個線程停止該線程。 我嘗試了這個:

timeToExit = true;
CloseHandle(stdinHandle);

並且代碼掛在CloseHandle

當程序正在運行的其他程序使用CreatePipeDuplicateHandle將我的程序輸入重定向到管道時,代碼將掛起。

那么,我該如何以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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM