文章目录
-
- 概述
- 继承关系
- 核心成员
-
- [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 对象生命周期管理的核心基类:
- 职责:管理对象的创建、所有权、终止和销毁
- 机制:通过所有权树和引用计数确保正确清理
- 应用:所有重要的 ZeroMQ 组件都继承自它
- 流程:支持优雅的终止流程,确保资源正确释放
- 线程安全:通过序列号和原子操作确保线程安全
这是 ZeroMQ 能够避免内存泄漏 和确保资源正确释放的关键机制!