可以停止cin等待输入? [英] Possible to stop cin from waiting input?

查看:371
本文介绍了可以停止cin等待输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在图形应用程序中,我使用控制台输入执行调试命令。当创建控制台时,还创建一个新线程来收集处理所有输入的用户命令,图形应用程序继续并行运行。我使用boost ::线程库。

In a graphical application I execute debug commands using the console input. When the console is created a new thread is also created to gather the user commands that handles all that input, the graphical application continues running parallel. I use boost::thread library.

到目前为止工作良好,但我没有找到一个好的解决方案停止执行这个线程。线程总是等待用户输入:

It works good so far, however I haven't found a nice solution to stop the execution of this thread. The thread is always waiting for a user input:

 while(appRunning)
 {
     std::cin>>theUserCommand;
     // ...do stuff
 }

结束,它将停止所有控制台功能,其中包括线程:

Then when the graphical application ends, it will stop all console functions, in which I include the thread:

 appRunning = false;
 // do some more related clean up
 myListeningThread->join();

正如你可以看到std :: cin将等待用户输入,称为。
我尝试的解决方案之一是创建事件synthetizing keystrokes,std :: cin将获得任何值发送与ENTER,线程将很好地结束,这个解决方案是可怕的,我不想保持它。
此外,它在工具被执行的环境中工作,但是当我尝试与UI API一起使用时失败。你能指导我如何以正确的方式解决这个问题?不能真的说,如果在C + +文件中有一个函数,停止std :: cin等待用户输入,只是和继续程序执行,是甚至可能吗?

As you can see the std::cin will be waiting for user input, after the join has being called. One of the solutions I tried is to create events "synthetizing keystrokes", the std::cin will get whatever value you send with an ENTER, the thread will end nicely, this solutions is horrible and I don't want to keep it. Besides, it did work in one of the environments the tool is executed, but fails when I tried using it along with a UI API. Could you guys guide me how can I fix this in a correct way? Can't really say for sure if in the C++ documentation there is a function to stop std::cin waiting for user input, and just and continue the program execution, is it even possible?

EDIT:Fine我发现keybd_event在某些环境中有点误导,用WriteConsoleInput显式指定输入处理程序工作良好。

Fine I find that keybd_event is a bit misleading for some environments, explicitly specifying the input handler with the WriteConsoleInput works good.

推荐答案

我不是一个Windows程序员,我知道更多关于Unix。我完全不熟悉 boost :: thread 。也就是说,根据此MSDN页面,这里是我的建议:

I am not much of a Windows programmer, I know a whole lot more about Unix. And I am totally unfamiliar with boost::thread. That said, based on the advice at the bottom of this MSDN page, here is my recommendation:

  • Create an event object before you create the console-reading thread.
  • When you want to shut down, call SetEvent on the event object immediately before calling the thread's ->join method.
  • Change the main loop in your console-reading thread to block in WaitForMultipleObjects rather than istream::operator>>, something like this:

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 。您需要使用低 - > - >控制台输入函数,特别是 GetNumberOfConsoleInputEvents ReadConsoleInput ,以确保你不阻塞;您需要在许多调用 processConsoleCommand 中累积字符,直到读取回车;您还需要自己回音。

  • This thread must take care not to do any blocking operation other than the WaitForMultipleObjects call. Per the discussion in the comments below, that means processConsoleCommand can't use cin at all. You will need to use the low-level console input functions instead, notably GetNumberOfConsoleInputEvents and ReadConsoleInput, to ensure that you do not block; you will need to accumulate characters across many calls to processConsoleCommand until you read a carriage return; and you will also need to do your own echoing.

    这篇关于可以停止cin等待输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆