多核上如何实现锁

发布于 2024-11-03 02:44:39 字数 404 浏览 1 评论 0原文

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

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 个核心/进程尝试向不同进程提供相同的锁会怎样?

For a uni-processor, the lock algorithm is pretty simple.

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
}

But how do we implement this code in multiprocessor/multicore systems. What if 2 cores/procs try to give the same lock to different processes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心作怪 2024-11-10 02:44:39

互斥体通常通过对单个内存值进行原子操作来实现。例如,锁可以是一个单词,当 0 时空闲,当 1 时锁定。要获取锁,处理器将锁定内存总线(因此其他处理器无法读取或写入内存),读取该字的最新值,如果1,则将其设置为1 code>0,并解锁内存总线。要解锁,可以将该字设置为0

这是一个简单的示例,没有解决争用锁时发生的情况。不同的操作系统使用不同的机制来处理该问题。 Linux 使用名为 futexes 的东西。我不确定 Windows 或 Mac 会做什么。

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

Mutexes are generally implemented with atomic operations on a single memory value. For instance, a lock can be a single word that is free when 0 and locked when 1. To acquire the lock, the processor will lock the memory bus (so no other processors can read or write to memory), read the most-current value of the word, set it to 1 if it is 0, and unlock the memory bus. To unlock, the word can be set to 0.

That's a simple example that doesn't address what happens when the lock is contended. Different OSs handle that using different mechanisms. Linux uses something called futexes. I'm not sure what Windows or Macs do.

Although the algorithm you posted is correct, non-kernel code can't disable CPU interrupts, so user-space code will tend to use atomic operations even on a single core.

晨曦÷微暖 2024-11-10 02:44:39

我说考虑锁的最简单方法是原子交换指令。下面获取一个锁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

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

I say the simplest way to think about the lock is an atomic exchange instruction. The following acquires a lock 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

The atomic exchange exists in most computers. Intel's x86 has an EXCHG instruction for this. Just FYI, Intel's x86 also has a compare-and-exchange instruction which takes care of the acquire as well as the compare for you. Basically, instead of first doing the exchange and then doing the test in software, it uses hardware and does the exchange only if X==0 to begin with. This saves an extra write to the variable X which reduces cache misses for X, leading to higher performance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文