原子操作:同步的基础
1. 原子编程中的内存回收问题
在原子编程里,内存回收是个常见问题。以多线程操作队列为例,若线程操作不当,像一个线程释放了某个节点的内存,而另一个线程还在引用该节点,就会引发程序崩溃。比如下面两种情况:
- 线程“唤醒后执行某操作,结果指针指向无效内存,导致程序崩溃。
- 线程“执行到某行被暂停,线程#完成一系列操作并释放了头节点内存,操作系统覆盖了线程“指向的内存,线程“唤醒后继续操作就会崩溃。
Michael和Scott提出了一种内存管理方法,即创建一个空闲列表(free list)。不直接删除节点,而是将其移到空闲列表中,后续再进行重用或删除。空闲列表可以是线程本地的,这样能避免昂贵的同步操作,但要确保不同线程的本地空闲列表不会有相同的指针,这有一定难度。
2. 修正错误队列的方法
文献中提到了四种修正错误队列的内存回收方法:
| 方法 | 描述 | 优点 | 缺点 |
| — | — | — | — |
| 基于静止状态的回收(QSRB) | 应用程序标记静止期,在此期间允许进行内存回收 | 速度快,线程同步需求少 | 难以确定用户空间的自然静止期,信号错误会导致数据竞争 |
| 基于时代的回收(EBR) | 应用程序通过中间层与存储交互,中间层存储足够信息来确定合适的回收时机 | 比QSRB更自动化 | 需要在数据访问前后进行同步操作 |
| 基于危险指针的回收(HPBR) | 每个线程维护一个危险指针集合,标记哪些指针在回收时是危险的 | 回收内存速度快 | 实现负担重,内存开销大 |
| 无锁引用计数(LFRC) | 指针附带一个原子计数器,
超级会员免费看
订阅专栏 解锁全文
9万+

被折叠的 条评论
为什么被折叠?



