深入理解无锁编程
扫描二维码
随时随地手机看文章
我学习无锁编程是Bruce Dawson 出色而全面的白皮书Lockless Programming Considerations(无锁编程的思考)。和许多技术一样,需要将理论付诸实践,在平台上开发和调试无锁代码。在这篇文章中,我想重新介绍无锁编程,首先是定义它,然后将大部分信息提炼为几个关键概念。我将使用流程图展示这些概念如何相互关联,然后我们将深入研究细节。至少,任何从事无锁编程的程序员都应该已经了解如何使用互斥锁和其他高级同步对象(如信号量和事件)编写正确的多线程代码。它是什么?人们通常将无锁编程描述为没有互斥锁的编程,互斥锁也称为锁。这是真的,但这只是故事的一部分。基于学术文献的普遍接受的定义更广泛一些。从本质上讲,无锁是一种用于描述某些代码的属性,而无需过多说明该代码的实际编写方式。基本上,如果您的程序的某些部分满足以下条件,那么该部分可以理所当然地被认为是无锁的。相反,如果代码的给定部分不满足这些条件,则该部分不是无锁的。
从这个意义上说,无锁中的锁并不直接指互斥锁,而是指以某种方式“锁定”整个应用程序的可能性,无论是死锁、活锁——甚至是由于由你最大的敌人。最后一点听起来很有趣,但这是关键。共享互斥锁被简单地排除在外,因为一旦一个线程获得互斥锁,您最大的敌人就再也不会调度该线程了。当然,真正的操作系统不是这样工作的——我们只是定义术语。
这是一个不包含互斥锁但仍然不是无锁的操作的简单示例。最初,X = 0。作为读者的练习,考虑如何以一种方式调度两个线程,使得两个线程都不退出循环。while(X == 0 ) {
X = 1 - X;
}
没有人期望大型应用程序是完全无锁的。通常,我们从整个代码库中识别出一组特定的无锁操作。例如,在一个无锁队列中,有可能是无锁的操作,比如极少数的
push
,pop
也许isEmpty
等。Herlihy