首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >种族状况。不知道为什么

种族状况。不知道为什么
EN

Stack Overflow用户
提问于 2021-04-22 15:13:52
回答 2查看 71关注 0票数 1

当我运行我的代码时,会出现种族状况。它是并发安全存储的简单实现。当我将get()方法中的接收者更改为(p *storageType)时,Race条件就消失了。我很困惑。我需要一个能向我解释这种行为的人。

代码语言:javascript
复制
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()
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-22 15:21:17

main()中,storage变量的类型为*storageType。如果storageType.Get()有值接收者,那么storage.get()的意思是(*storage).get()

get()调用以storageType作为累赘,因此必须取消storage指针变量的引用,以创建副本(将用作接收方值)。此复制意味着必须读取指定的storageType结构的值。但此读取与run()方法不同步,该方法读取和写入结构(其value字段)。

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

见可能的副本:Why does the method of a struct that does not read/write its contents still cause a race case?

票数 5
EN

Stack Overflow用户

发布于 2021-04-22 15:21:23

第一个:您的main函数不会等待所有的goroutines完成。当main回来的时候,所有的猩猩都会被迫返回。

查看使用sync.WaitGroup

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67216060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档