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

Asio: usage of self shared pointer in the examples

本文关键字:指针 共享 Asio      更新时间:2023-10-16

浏览 Asio 库的示例,例如这个(例如,第 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);
          }
        });
  }

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


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

上面的 -^^^- 是创建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引用计数。 因此,对原始shared_ptr的销毁不会破坏对象,而是将 self 保留为对所创建对象的引用。


还要知道 Lambda 可以比其调用者活得更久...... boost::asio::async_write 是一种异步方法,在复制其参数后立即返回。传递的 lambda 可能不会在您到达session生命周期结束之前执行。因此,如果没有 shared_from_this 创建的额外std::shared_ptr,析构函数将运行。该附加shared_ptr阻止session析构函数运行,直到调用 lambda 函数并破坏其参数。

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

你读过这个吗,如果没有,可能会有所帮助?