争用条件。不知道为什么

当我运行代码时,会发生争用条件。它是并发安全存储的简单实现。当我将 get() 方法中的接收方更改为 时,争用条件消失。我很困惑。我需要一个可以向我解释这样一个behaivior的人。(p *storageType)


package main


type 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()

    }

}


慕后森
浏览 101回答 2
2回答

翻翻过去那场雪

在变量中,类型为 。如果具有值接收器,则表示 。main()storage*storageTypestorageType.Get()storage.get()(*storage).get()调用作为接收器,因此必须取消引用指针变量以制作副本(将用作接收方值)。此复制意味着必须读取指向结构的值。但是此读取与读取和写入结构(其字段)的方法不同步。get()storageTypestoragestorageTyperun()value如果将 的接收器更改为指针(类型),则接收器将再次成为副本,但这次它将是指针的副本,而不是指向的结构。因此,不会发生结构的不同步读取。get()*storageType看到可能的副本:为什么不读/写其内容的结构的方法仍然会导致比赛情况?

侃侃尔雅

第一个:你的函数不会等待所有的 goroutine 完成。所有戈鲁丁人都被迫返回。mainmain考虑使用同步。等待组
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go