gpt4 book ai didi

multithreading - 了解互斥行为

转载 作者:行者123 更新时间:2023-12-01 22:30:42 25 4
gpt4 key购买 nike

我当时在想Go中的mutex会锁定数据,并且除非第一个goroutine释放锁定,否则不允许其他任何goroutine进行读取/写入。看来我的理解是错误的。阻止从其他goroutine读取/写入的唯一方法是也调用其他lock中的goroutines。这样可以确保只有一个critical section可以访问goroutine
因此,我希望this代码出现死锁:

package main

import(
"fmt"
"sync"
)

type myMap struct {
m map[string]string
mutex sync.Mutex
}

func main() {
done := make(chan bool)
ch := make(chan bool)
myM := &myMap{
m: make(map[string]string),
}
go func() {
myM.mutex.Lock()
myM.m["x"] = "i"
fmt.Println("Locked. Won't release the Lock")
ch <- true
}()

go func() {
<- ch
fmt.Println("Trying to write to the myMap")
myM.m["a"] = "b"
fmt.Println(myM)
done <- true
}()
<- done
}

由于第一个 goroutine锁定了该结构,因此我希望第二个 goroutine无法读取/写入该结构,但是这种情况不会在这里发生。
如果我将 mux.Lock()添加到第二个 goroutine中,那么将出现死锁。
我发现 mutex在Go中的工作方式有点怪异。如果我锁定了,那么Go不应允许任何其他 goroutine对其进行读写。
有人可以向我解释Go中的互斥量概念吗?

最佳答案

互斥锁周围没有神奇的力场,可以保护它恰好嵌入其中的任何数据结构。如果锁定了互斥锁,它将阻止其他代码对其进行锁定直到被解锁。仅此而已。 It's well documented in the sync package.
因此,在您的代码中,只有一个myM.mutex.Lock(),其效果与没有互斥锁的效果相同。
正确使用保护数据的互斥锁涉及在更新或读取数据之前锁定互斥锁,然后再对其进行解锁。通常,此代码将包装在一个函数中,以便可以使用defer:

func doSomething(myM *myMap) {
myM.mutex.Lock()
defer myM.mutex.Unlock()
... read or update myM
}

关于multithreading - 了解互斥行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63434403/

25 4 0