如何在多个内核上实现锁定

时间:2011-04-22 21:58:09

标签: operating-system mutex multicore locks multiprocessor

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

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个核心/过程尝试为不同的进程提供相同的锁定,那该怎么办呢?

2 个答案:

答案 0 :(得分:1)

互斥锁通常在单个内存值上使用atomic operations实现。例如,锁定可以是单个单词,在0时可以自由,在1时可以锁定。要获得锁定,处理器将锁定内存总线(因此没有其他处理器可以读取或写入内存),读取该字的最新值,如果是{{1}则将其设置为1 },并解锁内存总线。要解锁,可以将该字词设置为0

这是一个简单的例子,它没有解决锁争用时会发生什么。不同的OS使用不同的机制来处理。 Linux使用名为futexes的东西。我不确定Windows或Mac的用途。

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

答案 1 :(得分:0)

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

LOCK:
  set RegisterA = 1
  Atomic_Exchange(X, RegisterA)  //runs such that no other thread can work with X
  if RegisterA == 1:
    Means X was 1 when I esecuted the exchange thus someone else has the lock
    Since I do not have the lock, goto LOCK
  else:
    If A is zero, it means I was the first one to set X to 1, which means I own the lock

UNLOCK:
    X = 0

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