читать с клавиатуры с помощью boost async_read и posix :: stream_descriptor - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь захватить одиночные вводы с клавиатуры без блокировки внутри цикла while, используя boost asio async_read.Ожидается, что обработчик отобразит прочитанные символы.

Мой код:

    #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 = формат символа):

a
key input
b
c
d
e

Куда я иду не так?

Также программа очень интенсивно использует процессор.Как это исправить?

1 Ответ

0 голосов
/ 13 сентября 2018

Существует важное ограничение для асинхронного ввода-вывода с использованием stdin: Странный выброс исключения - назначить: операция не разрешена

Во-вторых, если вы используете async_read, не используйте std::cin вв то же время (вы просто сделаете два чтения).(Вместо этого посмотрите async_wait ).

Кроме того, вы должны быть в состоянии исправить высокую загрузку ЦП, правильно используя асинхронный ввод-вывод:

#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 был заменен цепочкой асинхронных операций.

...