如何解决了解互斥行为
我本以为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
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。