【问题标题】:Boost bind object freed on read handler在读取处理程序上释放的 Boost 绑定对象
【发布时间】:2013-03-15 18:11:58
【问题描述】:

我正在使用 Boost asio 打开多个套接字我使用一个集合,该集合具有指向具有所有套接字信息的自定义类的共享指针。这个类还具有async_receivehandle_read 函数,因为我需要对每个接收做不同的事情,我不能绑定额外的参数。

我遇到的问题是,当我关闭套接字时,我删除了对该指针的最后一个引用,因此在没有任何有效引用的情况下调用 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()handle_read 将被调用而关闭仍在处理中,因此“this”对象将在处理程序的任何位置释放。

【问题讨论】:

    标签: sockets boost-asio boost-thread


    【解决方案1】:

    听起来您很接近,但还不太了解通常使用 Boost.Asio 异步方法在应用程序中完成的共享所有权语义。您将希望在 binding your callback 处理程序时使用 shared_from_this(),以确保它们在异步操作期间保持在范围内。 io_service::~io_service() 文档 explains this 相当不错。

    当您需要提前停止异步操作时,cancel it 而不是在您的 SocketsAPI::do_close() 方法中关闭套接字。然后你的回调将得到一个错误代码boost::asio::error::operation_aborted,你可以用它来做出适当的反应。


    handle_read 将在关闭期间被调用 处理后,“this”对象将在处理程序的任何点被释放。

    这确实是一个单独的问题,您需要在处理程序回调中使用strands 到ensure exclusive access 来处理数据结构。

    【讨论】:

    • 感谢解决方案,这是我第一次使用 Asio,似乎很难掌握。在使用线程池时使用 shared_from_this 可以完美运行我在仅使用 1 个线程时仍然会崩溃,但这可能与原始问题无关。
    • @frisco 随时问另一个问题
    • 问题是我不确定问题是什么:D 我收到“Microsoft C++ 异常:boost::exception_detail::clone_impl<:exception_detail::error_info_injector>> 在内存位置 0x0672f4bc.." 但我不确定何时触发并且 VS 调试也无济于事。
    • @frisco 如果您用visual-c++boost 标记问​​题,我相信有人会提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多