【问题标题】:Implementation of Semaphores in kernel..?在内核中实现信号量..?
【发布时间】:2011-06-13 11:14:25
【问题描述】:

我正在阅读“操作系统概念”以了解信号量。 本书摘录:

“信号量的关键方面是它们以原子方式执行——我们 必须保证没有两个进程可以执行waitO和signal() 同时对同一个信号量进行操作。这是一个临界区 问题;并且在单处理器环境中(即只有一个 CPU 存在),我们可以通过在 wait() 和 signal() 操作正在执行。该方案在一个单一的工作 处理器环境,因为一旦中断被禁止,指令 来自不同进程的不能交错。只有当前运行的 进程一直执行,直到重新启用中断并且调度程序可以重新获得 控制。

在多处理器环境中,必须在每个 处理器;否则,来自不同进程的指令(运行在不同的 ent 处理器)可以以某种任意方式交错。禁用中断 在每个处理器上都可能是一项艰巨的任务,而且会严重降低 表现不错。因此,SMP 系统必须提供替代锁定 技术——例如 spinlocks——确保 waitO 和 signal0 是 以原子方式执行。”

我的问题是:

这个spinlock是如何实现的?使用像TestAndSet()这样的硬件指令?因为,在某些时候需要一些硬件支持(用户接受该支持或内核接受该支持),因为我们需要一条指令在一条指令中进行测试和设置(其间不能中断)。

虽然在书中,我找不到任何这样的陈述,即在某些时候需要一些硬件支持。它将信号量解释为实现同步的软件技术。这是误导吗?

【问题讨论】:

    标签: synchronization operating-system kernel semaphore interrupt


    【解决方案1】:

    如果没有某种硬件支持,就无法实现 SMP 自旋锁,在这种情况下是原子测试和设置和原子增量操作。请参阅here,了解它是如何在不同架构上完成的。

    有关它的 Linux/x86 实现,请参见 arch/x86/include/asm/spinlock.h。

    【讨论】:

      【解决方案2】:

      理论上,使用共享内存不需要原子操作来实现互斥。参见例如Dekker's algorithm。 但是,尽管这有效,但性能几乎不会受到影响。这就是为什么大多数处理器架构都支持原子指令(例如测试和设置/比较和交换)。另一个原因可能是缓存会使事情变得更加复杂——多个处理器可以有不同的内存视图。总而言之,原子指令导致的问题更少。

      【讨论】:

      • 现代 CPU 可能会重新排序指令,包括内存访问,并且 Dekker 的算法比信号量或自旋锁更受限制(只有两个进程;信号量也可用于在关键部分允许最多 N 个进程,例如N>1).
      • 您对指令重新排序是正确的,但是,尽管 Dekker 算法通常针对两个进程进行描述,但也可以针对 N 个进程进行细化。谈到指令重新排序,我相信通过在正确的点放置内存屏障,Dekker 算法也可以在新 CPU 上使用。但是,选择这些点肯定很复杂,信号量的性能可能非常糟糕。