我明白我使用了互斥锁,但我不明白它是如何工作的。我的意思是它是如何在里面工作的 它如何在锁定时排除另一个线程或进程,它如何知道谁是当前所有者等等? 有人可以在关于它的好文章上发布链接吗?只是我从程序员的角度找到它的工作原理,而不是它的实现。
答案 0 :(得分:2)
实施是特定于平台和语言的。
维基百科列出了几种流行的互斥算法和硬件解决方案。 https://en.wikipedia.org/wiki/Mutual_exclusion
Linux使用futex https://en.wikipedia.org/wiki/Futex
同时检查以前的讨论
答案 1 :(得分:2)
根据平台/语言,它的实现方式不同。我发现Go的implementation很高兴跟随(不是简单跟随,但或多或少清晰)
在那里,mutex
是一个包含两个字段,32位整数的结构:
type Mutex struct {
state int32
sema uint32
}
如果互斥锁尚未锁定,则操作基本上等于比较和交换指令:
// Fast path: grab unlocked mutex.
if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) {
if race.Enabled {
race.Acquire(unsafe.Pointer(m))
}
return
}
来自wikipedia的比较和交换是:
在计算机科学中,比较和交换(CAS)是多线程中用于实现同步的原子指令。它将内存位置的内容与给定值进行比较,并且只有它们相同时,才会将该内存位置的内容修改为新的给定值。
函数签名如下所示:
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
(你问这是怎么回事?How does Compare and Swap work?)
如果互斥锁未解锁,则Lock()
方法必须等待(阻止线程),直到它能够成功交换 Mutex
的州。
要记住的一点是,内存中的特定且不可变的地址对于保持Mutex
正常工作至关重要,也就是说,您无法复制互斥锁的值并将其传递 - 它是/它是指向内存中共享空间的指针。
有一些资源用于构建一个锁本身(虽然我发现golangs或多或少的简短实现足够好)
http://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks.pdf
https://www.andrew.cmu.edu/course/15-440-s12/applications/ln/lecture6.html