zmq源码分析之own_t

文章目录

    • 概述
    • 继承关系
    • 核心成员
      • [1. 所有权相关](#1. 所有权相关)
      • [2. 生命周期相关](#2. 生命周期相关)
      • [3. 选项相关](#3. 选项相关)
    • 构造函数
      • [1. 非 IO 线程对象](#1. 非 IO 线程对象)
      • [2. IO 线程对象](#2. IO 线程对象)
    • 核心功能
      • [1. 启动子对象](#1. 启动子对象)
      • [2. 终止子对象](#2. 终止子对象)
      • [3. 终止对象](#3. 终止对象)
      • [4. 处理终止](#4. 处理终止)
      • [5. 检查终止条件](#5. 检查终止条件)
    • 所有权层次结构
    • 应用场景
      • [1. Socket 管理](#1. Socket 管理)
      • [2. Session 管理](#2. Session 管理)
      • [3. IO 对象管理](#3. IO 对象管理)
    • 终止流程
    • 关键设计点
    • 总结

概述

own_t 是 ZeroMQ 中的对象所有权管理基类 ,负责管理对象的生命周期所有权层次 。它继承自 object_t,是许多 ZeroMQ 核心组件的基类。

继承关系

cpp 复制代码
class own_t : public object_t
{
    // 对象所有权和生命周期管理
};

继承 own_t 的类

  • socket_base_t(所有 socket 的基类)
  • session_base_t(会话基类)
  • io_object_t(IO 对象基类)
  • stream_engine_base_t(流引擎基类)
  • reaper_t(收割线程)
  • 等等

核心成员

1. 所有权相关

成员 类型 作用
_owner own_t * 指向拥有该对象的所有者
_owned std::set<own_t *> 该对象拥有的子对象集合

2. 生命周期相关

成员 类型 作用
_terminating bool 是否正在终止
_term_acks int 等待的终止确认数量
_sent_seqnum atomic_counter_t 已发送命令的序列号
_processed_seqnum uint64_t 已处理命令的序列号

3. 选项相关

cpp 复制代码
options_t options;  // socket 选项

构造函数

1. 非 IO 线程对象

cpp 复制代码
own_t::own_t (zmq::ctx_t *parent_, uint32_t tid_) :
    object_t (parent_, tid_),
    _terminating (false),
    _sent_seqnum (0),
    _processed_seqnum (0),
    _owner (NULL),
    _term_acks (0)
{
}

2. IO 线程对象

cpp 复制代码
own_t::own_t (zmq::io_thread_t *io_thread_, const options_t &options_) :
    object_t (io_thread_),
    options (options_),
    _terminating (false),
    _sent_seqnum (0),
    _processed_seqnum (0),
    _owner (NULL),
    _term_acks (0)
{
}

核心功能

1. 启动子对象

cpp 复制代码
void zmq::own_t::launch_child (own_t *object_)
{
    // 设置子对象的所有者
    object_->set_owner (this);

    // 将对象插入到 IO 线程
    send_plug (object_);

    // 获取对象所有权
    send_own (this, object_);
}

2. 终止子对象

cpp 复制代码
void zmq::own_t::term_child (own_t *object_)
{
    process_term_req (object_);
}

void zmq::own_t::process_term_req (own_t *object_)
{
    // 如果已经在终止过程中,忽略终止请求
    if (_terminating)
        return;

    // 如果找不到对象,说明已经发送过终止请求
    if (0 == _owned.erase (object_))
        return;

    // 注册终止确认
    register_term_acks (1);

    // 发送终止请求
    send_term (object_, options.linger.load ());
}

3. 终止对象

cpp 复制代码
void zmq::own_t::terminate ()
{
    // 如果已经在终止中,直接返回
    if (_terminating)
        return;

    // 如果没有所有者(根对象),自己终止自己
    if (!_owner) {
        process_term (options.linger.load ());
        return;
    }

    // 请求所有者终止自己
    send_term_req (_owner, this);
}

4. 处理终止

cpp 复制代码
void zmq::own_t::process_term (int linger_)
{
    // 确保不会重复终止
    zmq_assert (!_terminating);

    // 向所有子对象发送终止请求
    for (owned_t::iterator it = _owned.begin (), end = _owned.end (); it != end; ++it)
        send_term (*it, linger_);
    register_term_acks (static_cast<int> (_owned.size ()));
    _owned.clear ();

    // 开始终止流程
    _terminating = true;
    check_term_acks ();
}

5. 检查终止条件

cpp 复制代码
void zmq::own_t::check_term_acks ()
{
    if (_terminating && _processed_seqnum == _sent_seqnum.get ()
        && _term_acks == 0) {
        // 确保没有活跃的子对象
        zmq_assert (_owned.empty ());

        // 如果有所有者,发送终止确认
        if (_owner)
            send_term_ack (_owner);

        // 销毁对象
        process_destroy ();
    }
}

所有权层次结构

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                        所有权层次结构                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ctx_t (根所有者)                                                  │
│      │                                                              │
│      ├── reaper_t (收割线程)                                        │
│      │                                                                  │
│      └── io_thread_t[] (IO 线程池)                                  │
│              │                                                        │
│              └── stream_engine_base_t (流引擎)                      │
│                      │                                                │
│                      └── pipe_t (管道)                               │
│                                                                     │
│  socket_base_t (应用层 socket)                                       │
│      │                                                              │
│      └── session_base_t (会话)                                      │
│              │                                                        │
│              └── stream_engine_base_t (流引擎)                      │
│                      │                                                │
│                      └── pipe_t (管道)                               │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

应用场景

1. Socket 管理

socket_base_t 继承 own_t

cpp 复制代码
class socket_base_t : public own_t, public io_object_t
{
    // socket 的所有权管理
};

2. Session 管理

session_base_t 继承 own_t

cpp 复制代码
class session_base_t : public own_t, public i_poll_events
{
    // session 的所有权和生命周期管理
};

3. IO 对象管理

io_object_t 间接通过 own_t 管理

cpp 复制代码
class io_object_t : public i_poll_events
{
    // IO 对象通过 own_t 的机制管理生命周期
};

终止流程

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                         终止流程                                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. 调用 terminate()                                               │
│     └─> 如果没有所有者,自己终止                                     │
│     └─> 如果有所有者,向所有者发送终止请求                          │
│                                                                     │
│  2. process_term(linger)                                         │
│     └─> 向所有子对象发送终止请求                                    │
│     └─> 注册等待确认数量                                           │
│     └─> 设置 _terminating = true                                  │
│                                                                     │
│  3. 子对象终止                                                     │
│     └─> 子对象完成终止后发送 term_ack                             │
│                                                                     │
│  4. check_term_acks()                                             │
│     └─> 所有子对象已终止                                           │
│     └─> 所有命令已处理                                             │
│     └─> 没有等待中的确认                                           │
│     └─> 调用 process_destroy()                                     │
│                                                                     │
│  5. process_destroy()                                              │
│     └─> delete this                                                │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

关键设计点

设计点 说明
所有权转移 子对象的所有权可以转移
层次化管理 通过树形结构管理对象
引用计数 使用 term_acks 跟踪引用
序列号机制 确保命令顺序处理
延迟销毁 等待所有确认后再销毁
阻塞终止 支持 linger 超时控制

总结

own_t 是 ZeroMQ 对象生命周期管理的核心基类

  1. 职责:管理对象的创建、所有权、终止和销毁
  2. 机制:通过所有权树和引用计数确保正确清理
  3. 应用:所有重要的 ZeroMQ 组件都继承自它
  4. 流程:支持优雅的终止流程,确保资源正确释放
  5. 线程安全:通过序列号和原子操作确保线程安全

这是 ZeroMQ 能够避免内存泄漏确保资源正确释放的关键机制!

相关推荐
mounter6252 小时前
深度解析:Linux 内核为何要移除“直接映射” (Direct Map)?
linux·运维·服务器·security·linux kernel·direct mem map
带娃的IT创业者3 小时前
零停机迁移:如何将服务器成本从 $1432 降至 $233
运维·服务器·网络·成本优化·服务器迁移·零停机·hetzner
bugu___3 小时前
Linux系统、网络知识点回顾1
linux·网络
aixingkong9213 小时前
从伊朗网络设备瘫机-浅谈基础系统安全
网络·智能路由器·硬件架构·硬件工程
X7x54 小时前
网络基石:深入浅出路由交换技术,构建高效通信世界
网络·网络协议·交换技术
va学弟4 小时前
Agent入门开发
java·运维·服务器·ai
@insist1234 小时前
网络工程师-实战配置篇(二):精通 ACL 与策略路由,实现智能流量管控
大数据·网络·网络工程师·软考·软件水平考试
014-code4 小时前
Chronicle Queue:把 Disruptor 的数据落盘
java·服务器
QH139292318805 小时前
KEYSIGHT E5071C 端网络分析仪
网络·功能测试·嵌入式硬件·物联网·单元测试·集成测试·模块测试