我正在研究一个多线程应用程序,其中一个线程充当从客户端接收命令的tcp服务器.该线程使用Boost套接字和acceptor等待客户端连接,从客户端接收命令,将命令传递给应用程序的其余部分,然后再次等待.这是代码:
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
}
}
Run Code Online (Sandbox Code Playgroud)
这个线程大部分时间都在调用时被阻塞acceptor.accept().此时,线程仅在应用程序退出时终止.不幸的是,这会在main()返回后导致崩溃 - 我相信因为线程在单例被销毁后尝试访问应用程序的日志单例.(当我到这里时,就像那个,诚实的guv.)
当应用程序退出时,如何干净地关闭此线程?我已经读过可以通过从另一个线程关闭套接字来中断原始套接字上的阻塞accept()调用,但这似乎不适用于Boost套接字.我已经尝试使用Boost异步tcp echo服务器示例将服务器逻辑转换为异步i/o ,但这似乎只是为阻塞调用交换acceptor::accept()阻塞调用io_service::run(),所以我留下了同样的问题:一个阻塞打电话我不能打断.有任何想法吗?
我有一个侦听新连接的线程
new_fd = accept(Listen_fd, (struct sockaddr *) & their_addr, &sin_size);
Run Code Online (Sandbox Code Playgroud)
和另一个在关闭程序时关闭Listen_fd的线程.然而,在Listen_fd关闭后,它仍然会阻塞.当我使用GDB尝试和调试时,accept()不会阻塞.我认为这可能是SO_LINGER的问题,但默认情况下它不应该打开,并且在使用GDB时不应该更改.有什么想法,或关闭列表套接字的任何其他建议?