在图形应用程序中,我使用控制台输入执行调试命令。创建控制台时,还会创建一个新线程来收集处理所有输入的用户命令,图形应用程序继续并行运行。我使用 boost::thread 库。
到目前为止它运行良好,但是我还没有找到一个很好的解决方案来停止该线程的执行。线程一直在等待用户输入:
while(appRunning)
{
std::cin>>theUserCommand;
// ...do stuff
}
然后当图形应用程序结束时,它将停止所有控制台功能,我在其中包含线程:
appRunning = false;
// do some more related clean up
myListeningThread->join();
如您所见,调用连接后,std::cin 将等待用户输入。 我尝试的解决方案之一是创建事件“合成击键”,std::cin 将获得您使用 ENTER 发送的任何值,线程将很好地结束,这个解决方案很糟糕,我不想保留它。 此外,它确实在工具执行的环境之一中工作,但当我尝试将它与 UI API 一起使用时失败了。你们能指导我如何以正确的方式解决这个问题吗?不能确定 C++ 文档中是否有一个函数可以停止 std::cin 等待用户输入,然后继续执行程序,这是否可能?
编辑:很好,我发现 keybd_event 对于某些环境有点误导,使用 WriteConsoleInput 显式指定输入处理程序效果很好。
最佳答案
我不是 Windows 程序员,我对 Unix 了解更多。而且我完全不熟悉 boost::thread
。也就是说,根据 this MSDN page 底部的建议,这是我的建议:
- 创建一个 event object在创建控制台读取线程之前。
- 当你想关机时,调用
SetEvent
在调用线程的->join
方法之前立即在事件对象上。 将控制台读取线程中的主循环更改为在
WaitForMultipleObjects
中阻塞而不是istream::operator>>
,像这样:for (;;) { HANDLE h[2]; h[0] = GetStdHandle(STD_INPUT_HANDLE); h[1] = that_event_object_I_mentioned; DWORD which = WaitForMultipleObjects(2, h, FALSE, INFINITE); if (which == WAIT_OBJECT_0) processConsoleCommand(); else if (which == WAIT_OBJECT_0 + 1) break; else abort(); }
此线程必须注意不要执行除
WaitForMultipleObjects
调用之外的任何阻塞操作。根据下面评论中的讨论,这意味着processConsoleCommand
根本不能使用cin
。您将需要使用 low-level console input functions相反,特别是GetNumberOfConsoleInputEvents
和ReadConsoleInput
,以确保您不会阻塞;您将需要在对processConsoleCommand
的多次调用中累积字符,直到您读取回车;并且您还需要进行自己的回应。
关于c++ - 可以阻止 cin 等待输入吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8569027/