c++ - 可以阻止 cin 等待输入吗?

标签 c++ windows iostream blocking boost-thread

在图形应用程序中,我使用控制台输入执行调试命令。创建控制台时,还会创建一个新线程来收集处理所有输入的用户命令,图形应用程序继续并行运行。我使用 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相反,特别是 GetNumberOfConsoleInputEventsReadConsoleInput,以确保您不会阻塞;您将需要在对 processConsoleCommand 的多次调用中累积字符,直到您读取回车;并且您还需要进行自己的回应。

关于c++ - 可以阻止 cin 等待输入吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8569027/

相关文章:

c++ - ostringstream 插入器是否使用当前语言环境?

c++ - 使用 C++ 求解二阶 ODE 的 Runge-Kutta 四阶

windows - 哪个 Visual Studio 组件包含 MSVC Hostx 文件?

c++ - 将仿函数对象传递给模板类的构造函数

c - Malloc 是否分配了比需要的更多的内存?

windows - 为什么 "Content-Length: 0"在 POST 请求中?

qt - 如何在std::iostream中使用QFile?

c++ - 在 C++ 的一行中插入多个输入

c++ - 模棱两可的可变类成员访问

c++ - 带有Rcpp头文件的c++文件的编译步骤