Boost asio 在一段时间后停止处理
Boost asio stops processing after some amount of time
我有一个服务器应用程序,它使用 boost.asio 框架。应用程序逻辑很简单 - 它在多个端口上侦听传入连接,接受它,进行一些处理并关闭连接。当然,允许多个客户端同时连接到服务器。我使用异步方式接受连接读写数据。问题是,在某个时间点 io_service 只是停止处理处理程序。
让我更详细地描述症状。出现问题后,应用程序继续监听指定的端口,netstat 命令可以验证这一点。客户端可以与服务器建立连接,但没有调用单个处理程序(Server::Session)。
这是接受连接的代码:
void Server::StartAccept()
{
socket_ptr sock(new boost::asio::ip::tcp::socket(ioService_));
acceptor_.async_accept(*sock, boost::bind(&Server::Session, shared_from_this(), sock, boost::asio::placeholders::error));
}
void Server::Session(socket_ptr sock, const boost::system::error_code& error)
{
StartAccept();
if(error)
{
boost::system::error_code ec;
sock->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
sock->close(ec);
return;
}
//Processing...
}
这是启动服务器的代码:
void run_service()
{
for (;;)
{
try
{
io_service.run();
break;
}
catch (...)
{
}
}
}
boost::thread_group threads;
for ( int i = 0; i < size; ++i)
threads.create_thread(run_service);
threads.join_all();
我发现,如果我替换行
io_service.run();
和
while (!io_service.stopped())
io_service.run_once();
当出现错误时,这个循环会卡住,run_once 函数永远不会 return。
我对为什么会发生这种情况的假设:
- 处理程序之一,从未被调用 returns。
- 这是 boost 内部的某种死锁(因为我没有做任何锁定)。
问题是:
- 这种奇怪的行为还有哪些其他原因?
- 解决这个问题的最佳方法是什么?
- 我如何确定 run_once 函数在卡住之前调用了哪个处理程序?
问题出在等待另一个网络 activity 完成的处理程序中。这个 activity 没有超时,在某些情况下会永远持续下去。感谢您的评论。定义 BOOST_ASIO_ENABLE_HANDLER_TRACKING
确实是检测问题的好步骤。
我有一个服务器应用程序,它使用 boost.asio 框架。应用程序逻辑很简单 - 它在多个端口上侦听传入连接,接受它,进行一些处理并关闭连接。当然,允许多个客户端同时连接到服务器。我使用异步方式接受连接读写数据。问题是,在某个时间点 io_service 只是停止处理处理程序。
让我更详细地描述症状。出现问题后,应用程序继续监听指定的端口,netstat 命令可以验证这一点。客户端可以与服务器建立连接,但没有调用单个处理程序(Server::Session)。
这是接受连接的代码:
void Server::StartAccept()
{
socket_ptr sock(new boost::asio::ip::tcp::socket(ioService_));
acceptor_.async_accept(*sock, boost::bind(&Server::Session, shared_from_this(), sock, boost::asio::placeholders::error));
}
void Server::Session(socket_ptr sock, const boost::system::error_code& error)
{
StartAccept();
if(error)
{
boost::system::error_code ec;
sock->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
sock->close(ec);
return;
}
//Processing...
}
这是启动服务器的代码:
void run_service()
{
for (;;)
{
try
{
io_service.run();
break;
}
catch (...)
{
}
}
}
boost::thread_group threads;
for ( int i = 0; i < size; ++i)
threads.create_thread(run_service);
threads.join_all();
我发现,如果我替换行
io_service.run();
和
while (!io_service.stopped())
io_service.run_once();
当出现错误时,这个循环会卡住,run_once 函数永远不会 return。
我对为什么会发生这种情况的假设:
- 处理程序之一,从未被调用 returns。
- 这是 boost 内部的某种死锁(因为我没有做任何锁定)。
问题是:
- 这种奇怪的行为还有哪些其他原因?
- 解决这个问题的最佳方法是什么?
- 我如何确定 run_once 函数在卡住之前调用了哪个处理程序?
问题出在等待另一个网络 activity 完成的处理程序中。这个 activity 没有超时,在某些情况下会永远持续下去。感谢您的评论。定义 BOOST_ASIO_ENABLE_HANDLER_TRACKING
确实是检测问题的好步骤。