自旋锁(Spinlock)是一种 Linux 内核中广泛运用的底层同步机制。自旋锁是一种工作于多处理器环境的特殊的锁,在单处理环境中自旋锁的操作被替换为空操作。当某个处理器上的内核执行线程申请自旋锁时,如果锁可用,则获得锁,然后执行临界区操作,最后释放锁;如果锁已被占用,线程并不会转入睡眠状态,而是忙等待该锁,一旦锁被释放,则第一个感知此信息的线程将获得锁。
长期以来,人们总是关注于自旋锁的安全和高效,而忽视了自旋锁的“公平”性。传统的自旋锁本质上用一个整数来表示,值为1代表锁未被占用。这种无序竞争的本质特点导致执行线程无法保证何时能取到锁,某些线程可能需要等待很长时间。随着计算机处理器个数的不断增长,这种“不公平”问题将会日益严重。
排队自旋锁(FIFO Ticket Spinlock)是 Linux 内核 2.6.25 版本引入的一种新型自旋锁,它通过保存执行线程申请锁的顺序信息解决了传统自旋锁的“不公平”问题。排队自旋锁的代码由 Linux 内核开发者 Nick Piggin 实现,目前只针对 x86 体系结构(包括 IA32 和 x86_64),相信很快就会被移植到其它平台。
|
Linux 内核自旋锁的底层数据结构 raw_spinlock_t 定义如下:
清单 1. raw_spinlock_t 数据结构
|
slock 虽然被定义为无符号整数,但是实际上被当作有符号整数使用。slock 值为 1 代表锁未被占用,值为 0 或负数代表锁被占用。初始化时 slock 被置为 1。
线程通过宏 spin_lock 申请自旋锁。如果不考虑内核抢占,则 spin_lock 调用 __raw_spin_lock 函数,代码如下所示:
本文转自IBM Developerworks中国
本文介绍了Linux内核中自旋锁的应用,并着重探讨了传统自旋锁存在的不公平问题。随后,文章深入讲解了Linux 2.6.25版本引入的排队自旋锁如何解决这一问题。
337

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



