如何在不导致代码停止执行的情况下输入输入?在过去的20分钟里,我一直在寻找一个没有结果的答案。
cin >> string;
暂停代码AFAIK。
我需要使用多线程,还是有更好的方法? (我甚至不知道多线程是否有效。)
我最近开始学习c ++,至少可以说是初学者,所以请详细解释并包含我可能需要的任何库,谢谢。
答案 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::async
对std::launch::async
的调用在另一个线程上异步运行任务。 std::async
返回并行运行的任务句柄,称为 future 。此未来可用于检查任务是否完成。也可以使用成员函数std::future
从std::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.
}
}