win32:如何停止ReadFile(stdin |管道)

时间:2016-05-16 19:35:21

标签: c++ winapi

我有通过var http = require("http"), url = require("url"), path = require("path"), fs = require("fs") port = process.argv[2] || 8888; http.createServer(function(request, response) { var uri = url.parse(request.url).pathname , filename = path.join(process.cwd(), uri); path.exists(filename, function(exists) { if(!exists) { response.writeHead(404, {"Content-Type": "text/plain"}); response.write("404 Not Found\n"); response.end(); return; } if (fs.statSync(filename).isDirectory()) filename += '/index.html'; fs.readFile(filename, "binary", function(err, file) { if(err) { response.writeHead(500, {"Content-Type": "text/plain"}); response.write(err + "\n"); response.end(); return; } response.writeHead(200); response.write(file, "binary"); response.end(); }); }); }).listen(parseInt(port, 10)); console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown"); 得到的句柄,我有单独的线程来执行这样的代码:

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); 中挂起。

当程序由其他使用的程序运行时代码挂起 CloseHandleCreatePipe将我的程序输入重定向到管道。

那么我应该如何以win32方式停止DuplicateHandle线程? 或者可能是我应该如何更改while (!timeToExit)..线程以使其成为可能 停止它?

更新 在调用while (!timeToExit)..之前,我考虑过使用WaitForMultipleObjects stdin和event作为参数,并在其他线程中触发事件, 但是没有提到匿名管道作为ReadFile的可能输入,加上我尝试将stdin连接到控制台时, 在键入控制台的第一个字符后,它变得无用(总是无延迟地返回控制) 看起来我必须在这种情况下使用WaitForMultipleObjects,而不是ReadConsoleInput

3 个答案:

答案 0 :(得分:5)

从控制台的实际STDIN中读取时,您可以使用PeekConsoleInput()ReadConsoleInfo()代替ReadFile()

从(未)命名管道中读取时,请在致电ReadFile()之前使用PeekNamedPipe()

这将允许您在实际读取之前轮询STDIN以获取新输入,然后您可以在两次轮询之间检查线程终止状态。

您可以使用GetFileType()来检测STD_INPUT_HANDLE句柄附加的设备类型。

答案 1 :(得分:0)

最简单的解决方案是使用CancelSynchronousIo

答案 2 :(得分:-2)

最安全的方法是使用OVERLAPPED结构等异步调用ReadFile(非阻塞)。这可以从你的主线程完成。

如果/何时需要取消它,请调用CancelIo(来自调用ReadFile的同一线程)或CancelIoEx(如果来自其他线程)。

您可以使当前的方法有效;如果你将timeToExit标记为volatile,它可能不会挂起,但这种方法通常会产生更大的问题。