Я пытаюсь запустить выделенный поток, прикрепленный к ядру процессора, чтобы прочитать некоторые данные из веб-сокета.
Все ресурсы в этом ядре в основном предназначены для чтения данных из сокета и их анализа.
Мне не нужна высокая пропускная способность, мне нужен минимум задержка при чтении / декодировании / отправке сообщения, снижая дрожание до минимума.
Я использую 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();
}
Кажется, это решает мои проблемы, интересно, есть ли более эффективный / элегантный способ сделать это без необходимости связывать обратный вызов функции?