Я работаю над многопоточным приложением, в котором один поток действует как tcp-сервер, который получает команды от клиента. В потоке используется сокет Boost и акцептор для ожидания подключения клиента, получения команды от клиента, передачи команды остальной части приложения и последующего ожидания. Здесь код:
void ServerThreadFunc()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port_no));
for (;;)
{
// listen for command connection
tcp::socket socket(io_service);
acceptor.accept(socket);
// connected; receive command
boost::array<char,256> msg_buf;
socket.receive(boost::asio::buffer(msg_buf));
// do something with received bytes here
}
}
Этот поток тратит большую часть своего времени на вызов acceptor.accept()
. В настоящий момент поток прекращается только после выхода приложения. К сожалению, это приводит к сбою после возврата main() - я верю, потому что поток пытается получить доступ к протоколу однопользовательского входа приложения после того, как синглтон был уничтожен. (Это было так, когда я приехал сюда, честный гув.)
Как я могу закрыть этот поток до конца, когда придет время для выхода приложения? Я прочитал, что вызов блокировки accept() в сыром соке может быть прерван закрытием сокета из другого потока, но это не работает на разъем Boost. Я попытался преобразовать логику сервера в асинхронный ввод-вывод, используя Пример асинхронного tcp-эхо-сервера Boost, но это похоже на обмен блокирующим вызовом до acceptor::accept()
для блокирующего вызова io_service::run()
, поэтому я остаюсь с той же проблемой: заблокированный вызов, который я не могу прерывать. Любые идеи?