# 一、前言

阻塞机制Lock对于绝大多数应用程序都非常有用。如果正确使用,它们是快速且可靠的。但是它们也有一些缺点,有时需要我们考虑:
【1】它们会阻塞其他线程,休眠线程只能等待唤醒信号,其它什么也不能做:这可是在浪费宝贵的时间;
【2】它们可能会让你的应用程序挂起(hang住, 即不响应),如果一个持有锁的线程由于任何原因崩溃,锁本身永远不会被释放,其它等待中的线程将永远被卡住;
【3】你几乎无法控制哪个线程先休眠。通常由操作系统来选择要阻塞哪个线程。这可能会导致一个被称为优先级倒置的不利情况:正在执行非常重要的任务的线程被另一个优先级较低的线程阻塞。

大多数情况下,你不必关心这些问题,因为它们不会影响程序的正确性。但在另一方面,有时你需要让线程一直运行,特别是当你想充分利用多处理器/多核硬件时。也许是你无法承担因线程死亡而卡住的系统。或者优先级倒置问题已经严重到不能忽视的地步了

好消息是: 有另一种方法可以控制多线程应用程序中的并发任务,并能防止出现上述3点问题。它被称为lock-free programminglockless programming(都是无锁编程的意思),是一种在多个线程之间安全地共享不断变化的数据的技术,它无需锁定和解锁操作

坏消息是: 这是更底层(low level)的东西。比使用传统的同步原语(如互斥锁和信号量)低级得多:更接近硬件层。尽管如此,我发现无锁编程是一个很好的心智挑战,也是一个更好地理解计算机实际工作原理的好机会。

无锁编程依赖于atomic instructions原子指令,即CPU直接执行的原子操作。因为它是无锁编程的基础,在本文的其余部分中,我将首先介绍原子指令,然后演示如何将它们用于并发控制。我们开始吧!

# 二、原子指令

想象一下计算机执行的任何操作,例如在屏幕上显示图片。这种操作由许多较小的操作组成:将文件读入内存、对图像进行解压、点亮屏幕上的像素等等。如果你递归地放大其中一个子任务,也就是说,如果你把它分解成越来越小的部分,你最终会到达一个死胡同(即不可分解点)。由处理器执行的人类可见的最小的操作称为machine instruction机器指令,它是由硬件直接执行的命令。

(adsbygoogle = window.adsbygoogle || []).push({});