Я видел похожий пост здесь со схожей проблемой, но мой немного другой, и никакие ответы не помогли мне решить эту проблему. У меня есть многопоточный буст-сервер asio async HTTP, основанный на этом примере буста http / server3 . Я использую boost 1.64.0 и тестирую его на Windows 10 64 бит. Компиляция на VS 2015 64
У меня есть пул потоков, которые вызывают один экземпляр
io_service.run (). Основная идея с сервером заключается в том, что у меня есть пул потоков, которые все прослушивают входящие запросы. Когда я использую один поток, все работает отлично. Веб-страница загружается без проблем. но проблема возникает, когда я использую 2+ темы.
Если один поток не завершил свою работу (например, занят каким-либо POST-запросом, выполняющим некоторую работу с базой данных), сокет-получатель (случайным образом) не принимает некоторые запросы и ожидает завершения первого потока (запрос отображается как в ожидании на вкладке Сеть в Firefox). Иногда страница загружается без проблем, но чаще всего она останавливается, пока первый поток не завершит работу. Кто-нибудь знает, что может вызвать эту проблему?
Я пытался использовать определение BOOST_ASIO_ENABLE_HANDLER_TRACKING, чтобы отследить проблему, вот как она выглядит до остановки
@asio|1555450197.805179|3404*3407|strand@0000024EAAB649E0.dispatch
@asio|1555450197.805179|>3407|
@asio|1555450197.805179|3407*3408|socket@0000024EAAD400A0.async_send
@asio|1555450197.806177|<3407|
@asio|1555450197.806177|<3404|
@asio|1555450197.806177|>3405|ec=system:0
@asio|1555450197.806177|3405*3409|socket@0000024EAAB76D20.async_receive
accepting request
@asio|1555450197.806177|3405*3410|socket@0000024EA92D9CF0.async_accept
@asio|1555450197.806177|<3405|
@asio|1555450197.806177|>3408|ec=system:0,bytes_transferred=24530
@asio|1555450197.806177|3408*3411|strand@0000024EAAB649E0.dispatch
@asio|1555450197.806177|>3411|
@asio|1555450197.806177|<3411|
@asio|1555450197.806177|0|socket@0000024EAAD400A0.close
@asio|1555450197.806177|<3408|
@asio|1555450197.806177|>3409|ec=system:0,bytes_transferred=375
@asio|1555450197.807174|3409*3412|strand@0000024EAAB64580.dispatch
@asio|1555450197.807174|>3412|
@asio|1555450197.807174|3412*3413|socket@0000024EAAB76D20.async_send
@asio|1555450197.807174|<3412|
@asio|1555450197.807174|<3409|
@asio|1555450197.807174|>3413|ec=system:0,bytes_transferred=26952
@asio|1555450197.807174|3413*3414|strand@0000024EAAB64580.dispatch
@asio|1555450197.807174|>3414|
@asio|1555450197.807174|<3414|
@asio|1555450197.807174|0|socket@0000024EAAB76D20.close
@asio|1555450197.808173|<3413|
вот мой конструктор
boost::asio::ip::tcp::resolver resolver(io_service_);
boost::asio::ip::tcp::resolver::query query(address, port);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
acceptor_.open(endpoint.protocol());
acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor_.bind(endpoint);
acceptor_.listen();
boost::system::error_code error;
handle_accept(error);
моя ручка принимает функцию
void server::handle_accept(const boost::system::error_code& e)
{
if (!e)
{
new_connection_.reset(new connection(io_service_, *request_handler_, max_cont_lenght, min_upload_speed));
acceptor_.async_accept(new_connection_->socket(), [this](boost::system::error_code error)
{
this->start_accept(error);
});
}
}
функция начала приема
void server::start_accept(const boost::system::error_code& e)
{
if (!e)
{
new_connection_->start();
}
handle_accept(e);
}
функция запуска сервера
void server::run()
{
// Create a pool of threads to run all of the io_services.
for (std::size_t i = 0; i < thread_pool_size_; ++i)
{
std::shared_ptr<boost::thread> thread(new boost::thread(
[this](){
this->io_service_run();
}
));
threads.push_back(thread);
}
// Wait for all threads in the pool to exit.
for (std::size_t i = 0; i < threads.size(); ++i)
{
threads[i]->join();
}
}