gpt4 book ai didi

go - 跨例程共享内存

转载 作者:行者123 更新时间:2023-12-02 11:25:46 25 4
gpt4 key购买 nike

Go中的以下测试失败:

type A struct {
b bool
}

func TestWG(t *testing.T) {
var wg sync.WaitGroup
a := update(&wg)
wg.Wait()
if !a.b {
t.Errorf("error")
}
}

// Does not work
func update(group *sync.WaitGroup) A {
a := A{
b : false,
}
group.Add(1)
go func() {
a.b = true
group.Done()
}()
return a
}
最初,我认为这可能是由于 waitGroup.Done()中没有障碍而发生的,这可能解释了为什么将 update更改为
// works
func update(group *sync.WaitGroup) A {
a := A{
b : false,
}
group.Add(1)
go func() {
a.b = true
group.Done()
}()
time.Sleep(1*time.Second)
return a
}
作品。但是然后将返回类型更改为 pointer也可以使它工作
// works
func update(group *sync.WaitGroup) *A {
a := A{
b : false,
}
group.Add(1)
go func() {
a.b = true
group.Done()
}()
return &a
}
有人可以告诉我这里发生了什么吗?

最佳答案

您的第一个示例涉及数据竞赛!
您返回需要读取的a,并发goroutine(您刚刚启动的)会在不同步的情况下写入它。因此输出未定义! go test -race也证实了这一点。
添加 sleep 时也会发生同样的事情:数据争用仍然存在( time.Sleep() 而不是同步工具),因此结果仍然不确定! go test -race再次确认这一点。
当您将返回类型更改为指针时,您只需返回一个指向a的指针,而该指针不涉及读取a的值,并且启动的goroutine不会修改指针,而只是修改指向的值。并且调用方TestWG()正确地等待,直到使用waitgroup完成操作为止,因此此处没有发生数据争用。

关于go - 跨例程共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64264828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com