没有暂停代码的用户输入(c ++控制台应用程序)

时间:2014-09-30 17:55:07

标签: c++ multithreading console-application user-input cin

如何在不导致代码停止执行的情况下输入输入?在过去的20分钟里,我一直在寻找一个没有结果的答案。

cin >> string;暂停代码AFAIK。

我需要使用多线程,还是有更好的方法? (我甚至不知道多线程是否有效。)

我最近开始学习c ++,至少可以说是初学者,所以请详细解释并包含我可能需要的任何库,谢谢。

3 个答案:

答案 0 :(得分:8)

以下是一个示例,说明如何使用>>和另一个使用多线程的调用从标准输入流中读取令牌。

#include <iostream>
#include <thread>
#include <future>

int main() {
    // Enable standard literals as 2s and ""s.
    using namespace std::literals;

    // Execute lambda asyncronously.
    auto f = std::async(std::launch::async, [] {
        auto s = ""s;
        if (std::cin >> s) return s;
    });

    // Continue execution in main thread.
    while(f.wait_for(2s) != std::future_status::ready) {
        std::cout << "still waiting..." << std::endl;
    }

    std::cout << "Input was: " << f.get() << std::endl;
}

这里使用启动参数std::asyncstd::launch::async的调用在另一个线程上异步运行任务。 std::async返回并行运行的任务句柄,称为 future 。此未来可用于检查任务是否完成。也可以使用成员函数std::futurestd::future::get对象返回任务的结果。

我传递给std::async的任务是一个简单的lambda expression,它创建一个字符串,从流中读取一个标记到字符串中并返回它(""s是一个标准在C ++ 14中引入的文字,它返回一个空的std::string对象。)

在调用std::async之后,主线程继续执行语句(与异步运行的任务并行)。在我的示例中,执行while循环,只是等待异步任务完成。注意std::future::wait_for的使用,每次迭代只会阻塞2秒。 std::future::wait_for会返回状态,可以与之进行比较以检查任务是否已完成。

最后,对std::future::get的调用将返回异步运行任务的结果。如果我们还没有等待任务完成,那么调用将会阻塞,直到结果准备就绪。

注意不要同时读取主线程中的标准输入(并行),因为读取调用不是原子事务,数据可能会出现乱码。

答案 1 :(得分:1)

有两种算法可以在不阻塞的情况下获取输入(暂停)。第一个是轮询,第二个是事件(中断)。

轮询输入

轮询涉及定期检查输入。使用键盘,这可能是读取按键的键盘。使用串行端口,可能意味着检查接收寄存器的状态。

在某些系统上阻止或等待输入将包括永久轮询,直到收到输入。

输入事件

在某些平台上,检测到输入时会发送事件。例如,Windows操作系统收到按下某个键的事件,并将该消息发送到焦点任务。在嵌入式系统上,硬件可以在中断向量处取消引用函数指针。

阻止基于事件的系统上的输入意味着睡眠直到收到事件。

摘要

标准C ++语言不提供用于在不阻塞的情况下检索输入的标准函数。 C ++输入函数的实现取决于平台,可能会阻止也可能不会阻塞。例如,平台可以等到收到换行符,然后返回单个字符。

许多平台或操作系统都具有可以测试端口进行输入(轮询)或在输入发生时(事件驱动)得到通知的功能。由于您未指定所使用的平台,因此详细信息将在此处停止。

答案 2 :(得分:0)

使用kbhit()。

while(1)
{
    if(kbhit())
    {
        // do what ever you want.
    }
}