我有通过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);
中挂起。
当程序由其他使用的程序运行时代码挂起
CloseHandle
和CreatePipe
将我的程序输入重定向到管道。
那么我应该如何以win32方式停止DuplicateHandle
线程?
或者可能是我应该如何更改while (!timeToExit)..
线程以使其成为可能
停止它?
更新
在调用while (!timeToExit)..
之前,我考虑过使用WaitForMultipleObjects
stdin和event作为参数,并在其他线程中触发事件,
但是没有提到匿名管道作为ReadFile
的可能输入,加上我尝试将stdin连接到控制台时,
在键入控制台的第一个字符后,它变得无用(总是无延迟地返回控制)
看起来我必须在这种情况下使用WaitForMultipleObjects
,而不是ReadConsoleInput
?
答案 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,它可能不会挂起,但这种方法通常会产生更大的问题。