Asio:示例中自共享指针的使用

Asio: usage of self shared pointer in the examples

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

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


相关代码:

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

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);
          }
        });
  }

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

您是否阅读过 this,如果没有,它可能对您有所帮助?

std::enable_shared_from_this<> is to create an extra std::shared_ptr from the std::shared_ptr handle that owns the object calling shared_from_this成员函数的用途。


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

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

但是因为 start() method calls 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 是一种异步方法,returns 在复制其参数后立即执行。在您达到 session 生命周期结束 之前,传递的 lambda 可能不会执行。因此,如果没有 shared_from_this 创建的附加 std::shared_ptr,析构函数将 运行。额外的 shared_ptr 阻止了 session 的析构函数 运行ning,直到调用 lambda 函数并且它的参数被析构。