对于单处理器,锁定算法非常简单。
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个核心/过程尝试为不同的进程提供相同的锁定,那该怎么办呢?
答案 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的缓存未命中,从而提高了性能。