登录
首页 >  Golang >  Go问答

理解排他性行为

来源:stackoverflow

时间:2024-03-04 13:54:24 177浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《理解排他性行为》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

问题内容

我认为 go 中的 mutex 会锁定数据,并且不允许任何其他 goroutine 读/写,除非第一个 goroutine 释放锁定。看来我的理解是错误的。阻止其他 goroutine 读/写的唯一方法是在其他 goroutines 中调用 lock 。这将确保 关键部分 只能被一个 goroutine 访问。

所以,我希望这段代码会出现死锁:

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 无法读取/写入该结构,但这里不会发生这种情况。

如果我在第二个 goroutine 中添加 mux.lock() 那么将会出现死锁。

我发现 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
}

好了,本文到此结束,带大家了解了《理解排他性行为》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>