Estoy trabajando en una aplicación multiproceso en la que un hilo actúa como un servidor tcp que recibe comandos de un cliente. El subproceso usa un socket y aceptador de Boost para esperar a que un cliente se conecte, recibe un comando del cliente, pasa el comando al resto de la aplicación y luego espera nuevamente. Aquí está el código:Boost :: asio: ¿cómo interrumpir un hilo del servidor tcp bloqueado?
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
}
}
Este hilo pasa la mayor parte de su tiempo de bloqueo en la llamada a acceptor.accept()
. Por el momento, el hilo solo finaliza cuando la aplicación finaliza. Desafortunadamente, esto causa un bloqueo después de que main() regrese, creo que porque el subproceso intenta acceder al singleton de inicio de sesión de la aplicación después de que se destruye el singleton. (Fue así cuando llegué aquí, honesto).
¿Cómo puedo cerrar este hilo limpiamente cuando es hora de que la aplicación salga? He leído que una llamada de bloqueo de accept() en un socket sin procesar se puede interrumpir cerrando el socket de otro hilo, pero esto no parece funcionar en un socket Boost. Intenté convertir la lógica del servidor en E/S asíncrona usando el Boost asynchronous tcp echo server example, pero eso parece intercambiar una llamada de bloqueo al acceptor::accept()
por una llamada de bloqueo al io_service::run()
, así que me queda el mismo problema: una llamada bloqueada que no puede interrumpir ¿Algunas ideas?
Siempre hay ['io_service :: stop'] (http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/reference/io_service/stop.html), se puede llamar de otro hilo. –
La idea de tener un bucle de evento es que * todo * sucede en el bucle de evento, es decir, ejecutar(). Lo que significa que no tiene un segundo hilo de qué preocuparse en primer lugar. (aunque a veces tiene sentido hacer ciertas cosas fuera del ciclo de eventos, como cálculos exigentes) –
Use async_accept. –