Skip to content

大多数内核,包括 xv6 在内,都会交错执行多个活动。交错的一个来源是多处理器硬件:具有多个独立执行 CPU 的计算机,例如 xv6 的 RISC-V。这些多个 CPU 共享物理内存,xv6 利用这种共享来维护所有 CPU 读写的数据结构。这种共享带来了一种可能性,即一个 CPU 正在读取一个数据结构,而另一个 CPU 正在中途更新它,甚至多个 CPU 同时更新同一个数据;如果没有仔细的设计,这种并行访问很可能会产生不正确的结果或损坏数据结构。即使在单处理器上,内核也可能在多个线程之间切换 CPU,导致它们的执行交错。最后,如果设备中断处理程序修改了与某些可中断代码相同的数据,那么在错误的时间发生中断可能会损坏数据。术语并发指的是多个指令流由于多处理器并行、线程切换或中断而交错执行的情况。

内核中充满了并发访问的数据。例如,两个 CPU 可以同时调用 kalloc,从而并发地从空闲列表的头部弹出。内核设计者喜欢允许大量的并发,因为这可以通过并行来提高性能和响应能力。然而,因此,内核设计者必须确信尽管存在这种并发,代码仍然是正确的。有很多方法可以获得正确的代码,其中一些比其他的更容易推理。旨在在并发下保证正确性的策略以及支持它们的抽象称为并发控制技术。

Xv6 根据情况使用多种并发控制技术;还有更多可能的技术。本章重点介绍一种广泛使用的技术:。锁提供互斥,确保一次只有一个 CPU 可以持有锁。如果程序员为每个共享数据项关联一个锁,并且代码在使用一个项时总是持有相关的锁,那么这个项将一次只被一个 CPU 使用。在这种情况下,我们说锁保护了数据项。虽然锁是一种易于理解的并发控制机制,但锁的缺点是它们会限制性能,因为它们会序列化并发操作。

本章的其余部分将解释为什么 xv6 需要锁,xv6 如何实现它们,以及如何使用它们。