如何在不导致代码停止执行的情况下输入输入?在过去的 20 分钟里,我一直在寻找答案,但没有结果。
cin >> string;
暂停代码AFAIK。
我需要使用多线程,还是有更好的方法? (我什至不知道多线程是否可行。)
我最近开始学习 c++,至少可以说我是初学者,所以请彻底解释并包括我可能需要的任何库,谢谢。
原文由 Mandera 发布,翻译遵循 CC BY-SA 4.0 许可协议
如何在不导致代码停止执行的情况下输入输入?在过去的 20 分钟里,我一直在寻找答案,但没有结果。
cin >> string;
暂停代码AFAIK。
我需要使用多线程,还是有更好的方法? (我什至不知道多线程是否可行。)
我最近开始学习 c++,至少可以说我是初学者,所以请彻底解释并包括我可能需要的任何库,谢谢。
原文由 Mandera 发布,翻译遵循 CC BY-SA 4.0 许可协议
这是一个示例,说明如何使用 >>
与另一个使用多线程的调用并行地从标准输入流中读取令牌。
#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::launch::async
调用 std::async
在不同的线程上异步运行任务。 std::async
返回并行运行的任务的句柄,称为 future 。这个未来可用于检查任务是否完成。也可以使用成员函数 std::future::get
从 std::future
对象返回任务的结果。
我传递给 std::async
的任务是一个简单的 lambda 表达式,它创建一个字符串,从流中读取一个令牌并返回它( ""s
是引入的标准文字在 C++14 中返回一个空的 std::string
对象)。
调用 std::async
后主线程继续执行语句(与异步运行任务并行)。在我的示例中,执行了一个 while
循环,它只是等待异步任务完成。请注意使用 std::future::wait_for
每次迭代仅阻塞 2 秒。 std::future::wait_for
返回一个可以比较的 状态 来检查任务是否完成。
最后调用 std::future::get
会返回异步运行任务的结果。如果我们没有等待任务完成,调用将阻塞,直到结果准备好。
注意不要从主线程中的标准输入(并行)读取,因为读取调用 不是 原子事务并且数据可能会出现乱码。
原文由 Felix Glas 发布,翻译遵循 CC BY-SA 3.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
有两种算法可以在不阻塞(暂停)的情况下获取输入。第一个是轮询,第二个是按事件(中断)。
轮询输入
轮询涉及定期检查输入。使用键盘,这可能是读取键盘以进行按键操作。对于串行端口,这可能意味着检查接收寄存器的状态。
在某些系统上阻塞或等待输入将包括永远轮询,直到接收到输入。
输入事件
在某些平台上,当检测到输入时会发送一个事件。例如,Windows 操作系统接收到一个按键被按下的事件,并将消息发送到焦点任务。在嵌入式系统上,硬件可以取消引用中断向量处的函数指针。
在基于事件的系统上阻塞输入意味着休眠直到接收到事件。
概括
标准 C++ 语言不提供用于无阻塞地检索输入的标准函数。 C++ 输入函数的实现依赖于平台,可能会阻塞也可能不会阻塞。例如,平台可以等到收到换行符后再返回单个字符。
许多平台或操作系统都有功能,您可以在其中测试端口的输入(轮询)或在输入发生时收到通知(事件驱动)。由于您没有指定您使用的是哪个平台,所以详细信息到此为止。