boost asio - io_service не ждет подключения к потокам - PullRequest
0 голосов
/ 12 февраля 2020

Я хочу создать асинхронный сервер c с несколькими потоками. Когда я создаю thread_group и жду некоторых соединений в асинхронном режиме. Моя программа не ждет и термин сразу.

void Server::configServer() {
    _ip = boost::asio::ip::address_v4::from_string("127.0.0.1");
    boost::asio::ip::tcp::resolver resolver(_io_service);
    _endpoint = *resolver.resolve({tcp::v4(), _port});
    std::cout << "Server address: " << _ip.to_string() << ":" << _port << std::endl;

    _acceptor.close();
    _acceptor.open(_endpoint.protocol());
    _acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
    _acceptor.bind(_endpoint);
    _acceptor.listen();
    for (int i = 0; i < 8; ++i) {
        _threads.create_thread(boost::bind(&boost::asio::io_service::run, &_io_service));
    }
    _threads.join_all();
    std::cout << "Server is set up" << std::endl;
    run();
}

void Server::run() {
    Connection::pointer newConnection = Connection::create(_acceptor.get_io_service());
    std::cout << "Server is running" << std::endl;

    _acceptor.async_accept(newConnection->socket(),
        boost::bind(&Server::handleAccept, this, newConnection,
        boost::asio::placeholders::error));
}

void Server::handleAccept(Connection::pointer newConnection, const boost::system::error_code& error) {
    if (!error) {
        std::cout << "Reçu un client!" << std::endl;
        newConnection->start();
        run();
    }
}

Можете ли вы сказать мне, что я делаю не так?

1 Ответ

0 голосов
/ 12 февраля 2020

run работает до тех пор, пока есть какие-либо ожидающие обработки задачи / обработчики.

В вашем случае вы запустили run, затем был вызван первый метод async_. Таким образом, run немедленно завершается из-за отсутствия вызываемых обработчиков.

Вы должны инициировать некоторую асинхронную задачу, затем вызвать run или использовать объект с именем work guard . Вы не указали, какую версию Boost вы используете, но есть два варианта:

  • в старых io_service / io_context::work ( ref )
  • current, executor_work_guard ( ref )

В своем классе вы можете добавить executor_work_guard в качестве дополнительной переменной-члена:

class Server {
    boost::asio::io_context _io_service;
    boost::asio::executor_work_guard<boost::asio::io_context::executor_type> guard;

    Server() : ...., guard(boost::asio::make_work_guard(_io_service)) {

    }
};

при таком подходе , run не возвращается, даже если нет обработчиков для обработки.

...