mutex.Lock() 如何知道要锁定哪些变量?

How does a mutex.Lock() know which variables to lock?

我是新手,所以请保持温柔。

所以我已经在我的一些代码中使用互斥体几个星期了。我理解它背后的概念:锁定对某个资源的访问,与之交互(读取或写入),然后再次为其他人解锁。

我使用的互斥代码主要是复制-粘贴-调整。代码运行了,但我仍在努力了解它的内部工作原理。直到现在,我一直在结构中使用互斥锁来锁定结构。不过今天我发现了 this example,这让我完全不清楚互斥体实际上锁定了什么。下面是一段示例代码:

var state = make(map[int]int)

var mutex = &sync.Mutex{}

var readOps uint64
var writeOps uint64

// Here we start 100 goroutines to execute repeated reads against the state, once per millisecond in each goroutine.
for r := 0; r < 100; r++ {
    go func() {
        total := 0
        for {
            key := rand.Intn(5)
            mutex.Lock()
            total += state[key]
            mutex.Unlock()
            atomic.AddUint64(&readOps, 1)

            time.Sleep(time.Millisecond)
        }
    }()
}

这里让我感到困惑的是,互斥锁和它应该锁定的值之间似乎没有任何联系。直到今天我还以为互斥量可以锁定一个特定的变量,但是看这段代码似乎以某种方式锁定了整个程序只执行锁定下面的行,直到再次解锁 运行。我想这意味着所有其他 goroutine 都暂停了一会儿,直到再次解锁 运行。由于代码已编译,我想它可以知道 lock()unlock() 之间访问了哪些变量,但我不确定是否是这种情况。

如果所有其他程序都暂停片刻,这听起来不像真正的多处理,所以我猜我不太了解正在发生的事情。

任何人都可以帮助我了解计算机如何知道它应该锁定哪些变量吗?

lock access to a certain resource, interact with it (read or write), and then unlock it for others again.

基本上是。

What puzzles me here is that there doesn't seem to be any connection between the mutex and the value it is supposed to lock.

Mutex只是一个同步访问资源的互斥对象。这意味着,如果两个不同的 goroutine 想要锁定互斥量,则只有第一个可以访问它。第二个 goroutines 现在无限期地等待,直到它自己可以锁定互斥锁。与变量没有任何关系,您可以根据需要使用互斥量。例如只有一个http请求,只有一个数据库read/write操作或者只有一个变量赋值。虽然我不建议在这些示例中使用互斥锁,但总体思路应该变得清晰。

but looking at this code it seems to somehow lock the whole program into doing only the lines below the lock, until the unlock is ran again.

不是整个程序,只有每个想要访问同一个互斥量的goroutine才会等待,直到它可以。

I suppose that means that all the other goroutines are paused for a moment until the unlock is ran again.

不,他们不会停下来。他们执行直到他们想要访问相同的互斥体。

如果你想用一个变量专门对你的互斥量进行分组,为什么不创建一个结构?