【问题标题】:C++ asynchronous call best practiceC++ 异步调用最佳实践
【发布时间】:2012-07-25 01:53:21
【问题描述】:

我正在使用 boost::asio。我编写了一个负责从套接字异步读取的类。 在我的应用程序中,io_service 可以在一个应用程序运行期间多次停止和启动。 所以我不得不担心服务停止时内存泄漏。 我想到了两个解决方案:

  1. 请求异步请求的类为函数提供了一个用于 asio 读取的缓冲区,并负责释放该缓冲区。这是一个明显的解决方案,但我不喜欢它。将不需要的参数传递给函数看起来真的很奇怪。

  2. 智能指针绑定到回调。这里的例子: http://pastebin.com/p8nQ5NFi

现在我正在使用第二种解决方案,但无论我感觉如何,我都在发明一个轮子。异步调用中缓冲区清理的常见做法是什么?我的方法有什么隐藏的问题吗?

【问题讨论】:

    标签: c++ boost-asio


    【解决方案1】:

    shared_ptr 方法相当普遍。但是,可以将shared_ptr 作为实例对象传递给bind,而不是将shared_ptr 作为附加参数传递给this

    boost::shared_ptr< my_class > ptr( this );
    
    boost::asio::async_read( stream, buffer, 
      boost::bind( &my_class::read_handler, ptr, 
         boost::asio::placeholders::error
         boost::asio::placeholders::bytes_transferred ) );
    

    通常,由于实例将通过shared_ptr 进行管理,它可能在也可能不在this 的上下文中,所以最好使用Boost.SmartPointer 的enable_shared_from_this。当一个类从boost::enable_shared_from_this继承时,它提供了一个shared_from_this()成员函数,该函数将一个有效的shared_ptr实例返回给this

    class my_class: public boost::enable_shared_from_this< my_class >
    {
      void read()
      {
         boost::asio::async_read( stream, buffer, 
           boost::bind( &my_class::read_handler, shared_from_this(), 
              boost::asio::placeholders::error
              boost::asio::placeholders::bytes_transferred ) );
      }
    };
    
    boost::shared_ptr< my_class > foo( new my_class() );
    foo->read();
    

    在这个 sn-p 中,foo.get()foo-&gt;shared_from_this() 都指向同一个实例。这有助于防止难以定位的内存泄漏。例如,在原始示例代码中,如果AsyncReadHandler 的复制构造函数在尝试调用AsyncReadMessage 时抛出,则会在Protocol::AsyncReadMessage 中发生内存泄漏。 Boost.Asio 的asynchronous TCP daytime server 和许多examples 显示enable_shared_from_this 在Boost.Asio 中使用。为了更深入的了解,this 问题专门涵盖了异步 Boost.Asio 函数和shared_ptr


    另外,在原始代码中,将Protocol::AsyncHelper 设为模板类可能比将其设为具有模板成员函数的非模板类更容易。这将允许AsyncHelper 接受协议、流和处理程序作为构造函数参数,并将它们存储为成员变量。此外,它使bind 调用更易于阅读,因为它减少了需要传递的参数数量,并且由于成员函数不再是模板,因此无需指定它们的完整类型。 Here 是一个示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 2011-08-12
      • 2013-02-02
      • 2018-12-26
      • 2018-02-14
      相关资源
      最近更新 更多