Принудительно использовать 100% ЦП при синхронном использовании boost :: beast :: websocket - PullRequest
0 голосов
/ 09 мая 2020

Я пытаюсь запустить выделенный поток, прикрепленный к ядру процессора, чтобы прочитать некоторые данные из веб-сокета.

Все ресурсы в этом ядре в основном предназначены для чтения данных из сокета и их анализа.

Мне не нужна высокая пропускная способность, мне нужен минимум задержка при чтении / декодировании / отправке сообщения, снижая дрожание до минимума.

Я использую boost::beast / boost::asio для чтения данных из сокета в режиме синхронной блокировки, поэтому я отключил поддержку потоков в BOOST_ASIO_DISABLE_THREADS.

Код выглядит следующим образом:

while (state_.load(std::memory_order_acquire) == state::running) {
    ws_client_.read(buffer_);
    if (ws_client_.is_message_done()) {
       // ...
    }
}

Этот код работает нормально, но он не удовлетворяет мои потребности. Я вижу, что загрузка ЦП упала и большую часть времени поток спит.

Я читал, что правильный способ запустить службу boost::asio - это позвонить poll или poll_one в boost::asio::io_context, поэтому я пробовал это:

while (state_.load(std::memory_order_acquire) == state::running) {
    ioc.poll();
}

Это сохраняет загрузку ЦП на 100%, именно то, что я хочу. Итак, я делаю это:

void connect(...) {
    // connected =)
    ws.async_read(buffer, std::ref(*this));
}


void operator()(const boost::system::error_code& ec, std::size_t bytes_written) {
    // ... 

    // I'm done parsing, query next
    ws.async_read(buffer, std::ref(*this));           
}

void poll() {
    ioc.poll();
}

Кажется, это решает мои проблемы, интересно, есть ли более эффективный / элегантный способ сделать это без необходимости связывать обратный вызов функции?

...