увеличить многопоточный tcp сервер asio с синхронным вводом / выводом в заданном потоке - PullRequest
3 голосов
/ 30 ноября 2010

По сути, я пытаюсь реализовать универсальный многопоточный TCP-сервер, который может обрабатывать произвольные запросы для использования 2-мя разными серверами с немного разными потребностями.

Мои требования:

  1. Запрос не может начать обрабатываться, пока не будет получен весь первоначальный запрос.(По сути, у меня есть заголовок запроса фиксированного размера, который, помимо прочего, включает размер всего запроса).
  2. Обработка запроса может привести к множеству ответных сообщений запрашивающему клиенту.IE, как правило, запросы могут быть обработаны в одном ответе, но иногда, в ответ на длительные транзакции с базой данных, мне нужно связываться с клиентом, давая ему понять, что я все еще работаю, и не прерывать соединение.

Чтобы добиться этого, я довольно внимательно следил за примером № 2 сервера HTTP из boost v1.44.В общем, пример работал для простых случаев.Что я заметил, так это то, что когда я масштабируюсь до одновременной обработки нескольких запросов, сделанные мной изменения каким-то образом приводят к тому, что все запросы обрабатываются последовательно, одним потоком.Очевидно, что я делаю что-то не так.

Я не могу опубликовать весь фактический код, который я использую, из-за ограничений работодателя, но достаточно сказать, что я сохранил асинхронные вызовы, чтобы принять новыйподключений, но заменили асинхронное чтение / запись синхронными вызовами.Если есть конкретные фрагменты, которые, по вашему мнению, вам нужны, я могу посмотреть, что я могу сделать.

По сути, я ищу указатели на то, как использовать boost :: asio для многопоточного TCP-сервера.где отдельные соединения обрабатываются одним потоком с синхронным вводом / выводом.Опять же, имейте в виду, моя абстракция основана на примере http-сервера № 2 (один io_service на каждый процессор), но я гибок к альтернативе

Ответы [ 3 ]

2 голосов
/ 01 декабря 2010

Документация Boost.Asio предлагает использовать один io_service для приложения и вызывать io_service::run из пула потоков.

Для меня также не очевидно, почему вы не можете использовать асинхронные read и write в сочетании с deadline_timer объектами для периодического пинга ваших клиентов.Такой дизайн почти наверняка будет масштабироваться лучше, чем поток на соединение, используя синхронные reads и writes.

0 голосов
/ 30 ноября 2010

Если вы выполняете много синхронных операций ввода-вывода, ваш параллелизм ограничен количеством имеющихся у вас потоков. Я хотел бы предложить один io_service для всех ваших асинхронных операций ввода-вывода (т. Е. Всех запоминающих устройств, таймеров), как у вас сейчас, а затем решить, как работать с синхронным вводом-выводом.

Для синхронного ввода-вывода вам необходимо решить, какой будет ваш максимальный параллелизм. Поскольку он является синхронным и является вводом / выводом, вам потребуется больше потоков, чем процессорам, и решение будет основываться на том, сколько параллелизма ввода / вывода вы хотите. Используйте отдельный io_service, а затем используйте io_service :: dispatch () для распределения работы по потокам, выполняющим синхронную рабочую нагрузку.

Делая это таким образом, можно избежать проблемы остановки обработки вызовов ввода-вывода при других асинхронных событиях.

0 голосов
/ 30 ноября 2010

Некоторая диагностика: вы можете напечатать значение io_service_pool_.get_io_service() перед его использованием в следующем коде?

// from server.cpp
void server::handle_accept(const boost::system::error_code& e)
{
  if (!e)
  {
    new_connection_->start();
    new_connection_.reset(new connection(
          io_service_pool_.get_io_service(), request_handler_));
    acceptor_.async_accept(new_connection_->socket(),
        boost::bind(&server::handle_accept, this,
          boost::asio::placeholders::error));
  }
}

Вам нужно будет сохранить его во временном хранилище, прежде чем передавать его на new_connection_.reset();то есть, не звоните get_io_service() дважды для этого теста.

Сначала мы должны убедиться, что вы получаете новый io_service.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...