为了账号安全,请及时绑定邮箱和手机立即绑定

争用条件。不知道为什么

争用条件。不知道为什么

Go
慕后森 2022-08-24 18:44:33
当我运行代码时,会发生争用条件。它是并发安全存储的简单实现。当我将 get() 方法中的接收方更改为 时,争用条件消失。我很困惑。我需要一个可以向我解释这样一个behaivior的人。(p *storageType)package maintype storageType struct {    fc    chan func()    value int}func newStorage() *storageType {    p := storageType{        fc: make(chan func()),    }    go p.run()    return &p}func (p storageType) run() {    for {        (<-p.fc)()    }}func (p *storageType) set(s int) {    p.fc <- func() {        p.value = s    }}func (p storageType) get() int {    res := make(chan int)    p.fc <- func() {        res <- p.value    }    return <-res}func main() {    storage := newStorage()    for i := 0; i < 1000; i++ {        go storage.set(i)        go storage.get()    }}
查看完整描述

2 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超14个赞

在变量中,类型为 。如果具有值接收器,则表示 。main()storage*storageTypestorageType.Get()storage.get()(*storage).get()

调用作为接收器,因此必须取消引用指针变量以制作副本(将用作接收方值)。此复制意味着必须读取指向结构的值。但是此读取与读取和写入结构(其字段)的方法不同步。get()storageTypestoragestorageTyperun()value

如果将 的接收器更改为指针(类型),则接收器将再次成为副本,但这次它将是指针的副本,而不是指向的结构。因此,不会发生结构的不同步读取。get()*storageType

看到可能的副本:为什么不读/写其内容的结构的方法仍然会导致比赛情况?


查看完整回答
反对 回复 2022-08-24
?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

第一个:你的函数不会等待所有的 goroutine 完成。所有戈鲁丁人都被迫返回。mainmain

考虑使用同步。等待组


查看完整回答
反对 回复 2022-08-24
  • 2 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号