【问题标题】:Asio: usage of self shared pointer in the examplesAsio:示例中自共享指针的使用
【发布时间】:2016-05-04 19:40:27
【问题描述】:

查看 Asio 库 this one for example 的示例(例如,第 37 行),我看到有时他们会从中创建一个共享指针(他们将其命名为 self),并将其捕获到他们调用的 lambda 中一些asio函数,但我不明白它的目的是什么。我什至没有看到它使用过。

那么,他们为什么要这样做呢?


相关代码:

..在服务器类中...(创建会话的地方)

if (!ec)
{
    std::make_shared<session>(std::move(socket_))->start();
}

...session::start()成员方法:

void start()
  {
    do_read();
  }

...session::do_read() 成员方法(我的兴趣点在哪里):

void do_read()
  {
    auto self(shared_from_this());                    // <<< ---WHY THIS??????
    socket_.async_read_some(asio::buffer(data_, max_length),
        [this, self](std::error_code ec, std::size_t length)
        {
          if (!ec)
          {
            do_write(length);
          }
        });
  }

【问题讨论】:

    标签: c++ boost boost-asio shared-ptr


    【解决方案1】:

    std::enable_shared_from_this&lt;&gt; 的目的是从拥有调用shared_from_this 成员函数的对象的std::shared_ptr 句柄创建一个额外的std::shared_ptr


    if (!ec)
    {
         std::make_shared<session>(std::move(socket_))->start();
    }
    

    上面的-^^^-line 创建session 的地方。如您所见,std::make_shared 返回的std::shared_ptr 将在; 处销毁,这也应销毁创建的session...

    但是因为start() 方法调用do_read() 被定义为...

    void do_read()
      {
        auto self(shared_from_this());
        socket_.async_read_some(asio::buffer(data_, max_length),
            [this, self](std::error_code ec, std::size_t length)
            {
              if (!ec)
              {
                do_write(length);
              }
            });
      }
    

    self 增加了 shared_ptr 引用计数。所以 original shared_ptr 创建的销毁不会销毁对象,而是将 self 作为对创建对象的引用。


    还知道 Lambda 可以比它的调用者更长寿...boost::asio::async_write 是一个异步方法,它在复制它的参数后立即返回。在您的session 达到生命结束之前,传递的 lambda 可能不会执行。因此,如果没有shared_from_this 创建的额外std::shared_ptr,析构函数将运行。额外的 shared_ptr 会阻止 session 的析构函数运行,直到调用 lambda 函数并且它的参数被析构。

    【讨论】:

      【解决方案2】:

      您引用的 lambda 正在从类对象中捕获状态(例如 this 指针),它们需要确保在访问状态时对象仍然处于活动状态。请记住,这些 lambdas 是异步调用的,例如当有数据准备好读取时。最初实例化类的函数和异步 lambdas 因此都共享类实例的所有权。

      你读过this,如果没有,可能会有所帮助?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-05
        • 1970-01-01
        • 1970-01-01
        • 2017-05-14
        相关资源
        最近更新 更多