互斥锁的内部结构是什么?

What is inner structure of the mutex?

我知道我使用了互斥锁,但我不明白它是如何工作的。我的意思是它在内部是如何工作的。
它如何在锁定时排除其他线程或进程,它如何知道谁是当前所有者等等? 能不能有人post一篇link上的好文章介绍一下呢?只是我只是从程序员的角度发现它是如何工作的,而不是它的实现。

实现是特定于平台和语言的。

维基百科列出了几种流行的互斥算法和硬件解决方案。 https://en.wikipedia.org/wiki/Mutual_exclusion

Linux 搭配 futex https://en.wikipedia.org/wiki/Futex

同时查看之前的讨论

How are mutexes implemented?

根据 platform/language 它的实现方式不同。我发现 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,是:

In computer science, compare-and-swap (CAS) is an atomic instruction used in multithreading to achieve synchronization. It compares the contents of a memory location to a given value and, only if they are the same, modifies the contents of that memory location to a new given value.

函数签名如下所示:

func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)

(你问这是如何工作的?How does Compare and Swap work?

如果互斥没有解锁,那么Lock()方法将不得不等待(阻塞线程)直到它可以成功交换 Mutex 状态下的值。

要记住的一件事是,内存中特定且不可变的地址对于保持 Mutex 正常工作至关重要,也就是说,您不能复制互斥锁的值并将其传递——它s/its 指向内存中共享 space 的指针。


有一些资源可以自己构建锁(尽管我发现 golang 或多或少的简短实现已经足够好了)

http://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks.pdf

https://www.andrew.cmu.edu/course/15-440-s12/applications/ln/lecture6.html