我正在使用Boost asio打开几个套接字我使用一个集合,其中包含指向具有所有套接字信息的自定义类的共享指针。这个类还有handle_read
async_receive
函数,因为我需要对每个接收做不同的事情,我不能用额外的参数绑定。
我遇到的问题是,当我关闭套接字时,我删除了对该指针的最后一个引用,因此调用handle_read
函数时没有任何有效的引用,然后代码就会中断。
void SocketsAPI::do_close(const SocketInfo socket)
{
log("do_close");
if (!socket.m_socket || !socket.m_socket->is_open()) {
return;
}
boost::system::error_code errorcode;
socket.m_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
if (errorcode) {
trace("Closing failed: ", errorcode.message());
}
socket.m_socket->close(errorcode);
if (errorcode) {
trace("Closing2 failed: ", errorcode.message());
}
mapType::iterator iter = sockets.find(socket.key);
if (iter != sockets.end()) {
sockets.erase (iter);
}
log("do_close end");
}
确实我不希望调用handle_read
函数,但是我无法避免它,以及在多线程实现(多个线程调用io_service.run()
){{1在关闭仍在处理时将被调用,因此“this”对象将在处理程序的任何一点被释放。
答案 0 :(得分:2)
听起来你很接近,但还不太了解通常使用Boost.Asio异步方法的应用程序完成的共享所有权语义。您需要在binding your callback处理程序时使用shared_from_this()
,以确保它们在异步操作期间保持在作用域内。 <{1}}文档explains this非常好。
当您需要提前停止异步操作时,cancel it而不是关闭io_service::~io_service()
方法中的套接字。然后,您的回调将被赋予错误代码boost::asio::error::operation_aborted
,您可以使用它来做出适当的反应。
在关闭仍然存在时将调用
SocketsAPI::do_close()
处理后,“this”对象将在处理程序的任何位置释放。
这实际上是一个单独的问题,您需要将handle_read
s ensure exclusive access用于处理程序回调中的数据结构。