c++ - 使用 boost async_read 和 posix::stream_descriptor 从键盘读取
问题描述
我正在尝试使用 boost asio async_read 在 while 循环内以非阻塞方式捕获单个键盘输入。处理程序应显示读取的字符。
我的代码:
#include <boost/asio/io_service.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/read.hpp>
#include <boost/system/error_code.hpp>
#include <iostream>
#include <unistd.h>
#include <termios.h>
using namespace boost::asio;
void read_handler(const boost::system::error_code&, std::size_t)
{
char c;
std::cin>>c;
std::cout << "keyinput=" << c << std::endl;
}
int main()
{
io_service ioservice;
posix::stream_descriptor stream(ioservice, STDIN_FILENO);
char buf[1];
while(1)
{
async_read(stream, buffer(buf,sizeof(buf)), read_handler);
ioservice.run();
}
return 0;
}
我的输出不符合预期(keyinput=char 格式):
a
key input
b
c
d
e
我哪里错了?
该程序也非常占用CPU。如何纠正它?
解决方案
使用标准输入对异步 IO 有一个重要限制:奇怪的异常抛出 - 分配:不允许操作
其次,如果你使用async_read
不要同时使用std::cin
(你只会做两次读取)。(请查看async_wait代替)。
除此之外,您应该能够通过正确使用异步 IO 来修复高 CPU 负载:
#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;
int main()
{
io_service ioservice;
posix::stream_descriptor stream(ioservice, STDIN_FILENO);
char buf[1] = {};
std::function<void(boost::system::error_code, size_t)> read_handler;
read_handler = [&](boost::system::error_code ec, size_t len) {
if (ec) {
std::cerr << "exit with " << ec.message() << std::endl;
} else {
if (len == 1) {
std::cout << "keyinput=" << buf[0] << std::endl;
}
async_read(stream, buffer(buf), read_handler);
}
};
async_read(stream, buffer(buf), read_handler);
ioservice.run();
}
如您所见,while
循环已被一系列异步操作取代。
推荐阅读
- odoo - Odoo - odoo 配置文件中的 xmlrc_port 和 http_port 参数有什么区别?
- c++ - 如何将 CLI 类的函数指针作为参数传递给 C++ 方法
- ruby-on-rails - gem安装权限问题
- javascript - 无法将 javascript 链接到 html 文件?
- reactjs - 将 Material UI react-autosuggest 功能转换为基于类组件
- cmd - Bazel genrule 检查位置表达式是否扩展为无文件
- c - 通过 C API 访问 tensorflow 2.0 SavedModel 的输入和输出张量
- machine-learning - 在 scikit-learn 中使用 OneVsRest 分类时,每个分类器的负数据点集是多少?
- android - 打开应用程序时是否可以删除白屏?
- react-native - 在 React -native 的 native-base 中更改 I18nManager.forceRTL(true) 时选项卡未呈现