C++ Hazard Pointer 内存安全回收机制详解
一、什么是 Hazard Pointer?
Hazard Pointer(HP,危险指针)是一种用于无锁(lock-free)数据结构的内存回收机制。其核心思想是:线程在访问某个共享对象前,先将其地址发布到一个'危险指针'槽中,告知其他线程'我正在使用这个对象,不要回收它'。
基本定义:
- 每个线程独占写入
- 用于声明'我正在访问这个对象'
- 防止该对象被其他线程释放
数学表达: 设 $H_i$ 为线程 $i$ 的 hazard pointer,$O$ 为某对象。 若 $\exists i : H_i = O$,则 $O$ 不可被回收。
二、为什么使用 Hazard Pointer?
问题背景
在无锁数据结构中:
- 一个线程删除节点
- 另一个线程仍然可能正在访问该节点
- 如果立即
free→ 产生 Use-After-Free (UAF) 错误
目标
保护'可能被并发删除'的动态对象,确保生命周期安全。
三、核心保护流程
读线程流程
- 读取共享指针
- 将该指针写入自己的 hazard pointer
- 再次验证共享指针未改变(Double-check)
- 安全访问对象
删除线程流程
- 从数据结构中移除对象
- 放入'待回收列表'
- 扫描所有 hazard pointers
- 若无人引用 → 才
free
双重检查的重要性
防止以下情况:
Thread A: 读 head
Thread B: 删除并释放 head
Thread A: 设置 hazard pointer
如果不验证,会保护'已经被释放的内存'。验证确保 Load1 == Load2。
四、完整代码示例
全局结构
#include <atomic>
#include <vector>
#include <thread>
constexpr int MAX_THREADS = ;
std::atomic<*> hazard_pointers[MAX_THREADS];

