Erlang 运行时中使用的读写锁解析
本文介绍了Erts中使用的读写锁(rwmutex,或称为rwlock)的原理和实现。在R14B中,Erts的读写锁进行了一次重要的性能更新,本文对这一次更新的优化进行了描述。此外还简单介绍了一下代码中使用的基本模式。
相比互斥锁,读写锁为临界区提供了一种粒度更细的锁机制。当有读者获得了读锁的时候, 那么所有读者线程都可以并发获得读锁,但是写者不能获得写锁。当写者获得了写锁的时候,这 个线程可以对临界区进行排他访问。
Erlang 运行时中使用的读写锁用于很多地方,例如 ETS 表、atom 表、cpuinfo、进程的注册名 表和分布表等内部数据结构,因此读写锁的性能对于 Erts 来说至关重要。根据 Rickard Green 在 EUC 2010 上的演讲提供的信息(本文部分内容参考了这个演讲的幻灯片1),Erts 中要使用自己的 读写锁而不是 Pthread 提供的读写锁的原因是:在使用偏向于读策略的时候,Pthread 读写锁会导 致写者饿死,因而解决方法是让使用 Erts 原来自带的 fallback 实现,而这个 fallback 实现的性能不 佳。所以 Erlang/OTP 小组开发了新的读写锁。相比 Linux 下使用的 NPTL 的 Pthread 提供的读写 锁,新的读写锁没有特别适用偏向于读者或写者的策略,在发生争用的时候将读者和写者交错 开,不会导致线程饿死,此外算法对于读者和写者都是公平的,满足 FIFO 的服务顺序。
本文第 2 节讲解 Erts 中普通读写锁的基本实现原理。第 3 节讲解普通读写锁在多核系统下的 性能问题以及针对读者优化实现的基本原理。第 4 节对读写锁实现的数据结构和代码结构进行了 简单的分析。
本文基于的 Erlang/OTP 版本是 R15B02。
本文依然使用LaTeX排版输出pdf,地址为
http://vdisk.weibo.com/s/nIU2y
欢迎下载!