Operating system 为什么在信号量操作期间必须禁用所有中断?

Operating system 为什么在信号量操作期间必须禁用所有中断?,operating-system,semaphore,mutual-exclusion,Operating System,Semaphore,Mutual Exclusion,我正在阅读加尔文的《操作系统概念》。在信号量部分,它指出在修改信号量值时,必须禁用处理器的所有中断。 为什么需要它?必须以原子方式修改信号量值。在单核系统上,这可以通过禁用中断来实现,这样更改信号量的读/修改/写操作就不会被中断 在多核系统上,仅禁用中断是不够的,因此多核处理器通常有原子指令来进行修改。例如,在Intel/AMD处理器上,有一个锁前缀使指令以原子方式执行 因此,加尔文并不完全正确。如果在修改信号量值的过程中允许处理器中断,那么该值可能最终处于不一致的状态。在中断期间,将执行一组特

我正在阅读加尔文的《操作系统概念》。在信号量部分,它指出在修改信号量值时,必须禁用处理器的所有中断。
为什么需要它?

必须以原子方式修改信号量值。在单核系统上,这可以通过禁用中断来实现,这样更改信号量的读/修改/写操作就不会被中断

在多核系统上,仅禁用中断是不够的,因此多核处理器通常有原子指令来进行修改。例如,在Intel/AMD处理器上,有一个锁前缀使指令以原子方式执行


因此,加尔文并不完全正确。

如果在修改信号量值的过程中允许处理器中断,那么该值可能最终处于不一致的状态。在中断期间,将执行一组特定的指令。原则上,这些指令可以执行与任何执行代码相同的操作。具体来说,中断可以在其逻辑中使用信号量的值,或者将该值复制到其他地方。如果该值处于不一致状态,则可能会中断代码逻辑。

禁用中断,以防止调度程序在执行信号量操作时取消“线程”(执行信号量操作)的调度。

在许多操作系统上,向信号量发送单元是中断状态支持的少数几个内核同步操作之一。这意味着来自用户代码的信号量post或wait调用可能会被中断,然后由中断驱动程序的post重新输入。必须非常小心地处理信号量状态(等待线程的计数和队列),以确保它保持内部一致性并正确运行。这可能涉及暂时禁用所有中断,以便以安全的方式更新计数、索引和指针

这不仅仅是一个原子指令的问题——信号量post可以使等待的线程准备好运行或运行,这意味着将线程控制块从信号量等待队列移动到准备好的队列(可能具有优先级提升),抢占另一个内核上运行的线程,而不是处理驱动程序中断的线程,并将先前等待的线程分派到该内核上


如果允许中断post/wait操作并从中断处理程序重新输入,则此类复杂操作仍必须正常工作,因此,毫不奇怪,操作系统开发人员试图通过禁用同步处理关键部分周围的所有中断来缓解问题。

一些系统具有用于此类目的的不间断指令。中断并不是真正被阻塞的,而是在这个过程中中断永远不会发生

一些系统可以禁用中断组,同时允许其他系统继续

其他系统在修改上述结构时需要阻塞中断


我还澄清了锁前缀(以及其他系统上的等价物)防止在另一个处理器执行指令期间进行修改。

在SMP系统中会发生什么情况?在每个处理器上禁用中断并不能确保原子性,对吗?我问这个问题是因为书中提到我们需要禁用每个处理器上的中断,以确保构成wait()和signal()操作(在信号量上)的指令不会交错发生,但这对我来说毫无意义。。。