7

对于单处理器,锁定算法非常简单。

Lock(threadID) {
  Disable Interrupts
  If lock is already owned by same thread{
    Restore Interrupts
    return
  }
  if lock is free {
    make lock busy
    set current thread as the owner of the lock
  }
  else {
     add threadID to the lock queue.
  }
  Restore Interrupts
  return
}

但是我们如何在多处理器/多核系统中实现此代码。如果 2 个核心/进程尝试为不同的进程提供相同的锁怎么办。

4

2 回答 2

1

互斥锁通常通过对单个内存值的原子操作来实现。例如,一个锁可以是一个单词,它在什么时候是空闲的,0而在什么时候是锁定的1。为了获得锁,处理器将锁定内存总线(因此没有其他处理器可以读取或写入内存),读取该字的最新值,将其设置为1if 它是0,然后解锁内存总线。要解锁,可以将单词设置为0

这是一个简单的例子,它没有说明当锁被争用时会发生什么。不同的操作系统使用不同的机制来处理。Linux 使用一种叫做futexes的东西。我不确定 Windows 或 Mac 能做什么。

尽管您发布的算法是正确的,但非内核代码无法禁用 CPU 中断,因此即使在单个内核上,用户空间代码也会倾向于使用原子操作。

于 2011-04-23T14:37:40.057 回答
0

我说考虑锁的最简单方法是原子交换指令。以下获取锁 X。

锁:
  设置寄存器A = 1
  Atomic_Exchange(X, RegisterA) //运行使得没有其他线程可以使用 X
  如果寄存器A == 1:
    意味着当我进行交换时 X 为 1,因此其他人拥有锁
    由于我没有锁,请转到 LOCK
  别的:
    如果 A 为零,则意味着我是第一个将 X 设置为 1 的人,这意味着我拥有锁

开锁:
    X = 0

原子交换存在于大多数计算机中。英特尔的 x86 对此有一个 EXCHG 指令。仅供参考,英特尔的 x86 还具有比较和交换指令,可以为您处理获取和比较。基本上,它不是首先进行交换然后在软件中进行测试,而是使用硬件并且仅在 X==0 开始时才进行交换。这节省了对变量 X 的额外写入,从而减少了 X 的缓存未命中,从而提高了性能。

于 2011-05-10T00:56:07.013 回答