zoukankan      html  css  js  c++  java
  • muduo网络库TcpConnection对象生存期管理

    为什么释放一个TcpConnection会如此复杂?

      首先要知道客户端关闭连接,在服务端TcpConnection对象所属的Channel对象返回的是可读事件。

      因此从TcpServer的map<string, shared_ptr<TcpConnection>>中移除这个TcpConnection对象都是在TcpConnectoin所属的Channel对象的Channel::handleEvent()函数内进行的。

      如果在这个TcpConnection对象的函数执行过程中释放了这个对象,那么就会造成不可预计的后果。(大概率就是coredump)

      因此待释放的TcpConnection对象的生命期一定要长于Channel::handleEvent()函数。

    如何做到正确释放一个TcpConnection对象的?

    最重要的是在每一个TcpConnection建立的时候将他的shared_ptr赋值给了他所属的Channel对象的weak_ptr。

    void TcpConnection::connectEstablished()
    {
      loop_->assertInLoopThread();
      assert(state_ == kConnecting);
      setState(kConnected);
      channel_->tie(shared_from_this());
      channel_->enableReading();
      connectionCallback_(shared_from_this());
    }

    这样当有TcpConnection所属的Channel有事件到来的时候就可以对TcpConnection的引用计数+1:此时TcpServer的map中有一个智能指针指向TcpConnection

    void Channel::handleEvent(Timestamp receiveTime)
    {
      std::shared_ptr<void> guard;
      if (tied_)
      {
        guard = tie_.lock();
        if (guard)
        {
          handleEventWithGuard(receiveTime);
        }
      }
      else
      {
        handleEventWithGuard(receiveTime);
      }
    }

    整一个流程为:

    简略的函数压栈情况:

  • 相关阅读:
    SQL Server 使用日志传送
    SQL Server 2008 R2 主从数据库同步
    JavaScript及C# URI编码详解
    sql server日期时间函数
    ASP.NET Core在Azure Kubernetes Service中的部署和管理
    [Nuget]Nuget命令行工具安装
    利用HttpListener创建简单的HTTP服务
    短链接实现
    [ubuntu]中文用户目录路径改英文
    [ubuntu]deb软件源
  • 原文地址:https://www.cnblogs.com/jialin0x7c9/p/12562981.html
Copyright © 2011-2022 走看看