gpt4 book ai didi

go - 使用WaitGroup从不同的go例程阻塞当前变量写入堆栈变量是否安全?

转载 作者:行者123 更新时间:2023-12-01 22:39:40 24 4
gpt4 key购买 nike

有各种任务执行器,具有不同的属性,其中一些只支持非阻塞调用。所以,我在想,是否需要使用 mutex/channel 来安全地将任务结果传递给调用 go-routine,或者是否足够简单 WaitGroup ?

为了简单起见和问题的具体性,一个使用非常幼稚的任务执行器启动功能直接作为 goroutine 的示例:

func TestRace(t *testing.T) {
var wg sync.WaitGroup

a, b := 1, 2

wg.Add(1)

// this func would be passed to real executor
go func() {
a, b = a+1, b+1
wg.Done()
}()

wg.Wait()

assert.Equal(t, a, 2)
assert.Equal(t, b, 3)
}

使用 -race 执行上述测试选项没有失败,在我的机器上。然而,这样的保证就足够了吗?如果 go-routine 在不同的 CPU 内核、CPU 内核 block (AMD CCX) 或多插槽设置中的不同 CPU 上执行会怎样?

所以,问题是,我可以使用 WaitGroup为非阻塞执行器提供同步(阻塞和返回值)?

最佳答案

JimB 或许应该提供这个作为答案,但我会从 his 复制它comments , 从 this one 开始:

The WaitGroup here is to ensure that a, b = a+1, b+1 has executed, so there's no reason to assume it hasn't.



[和]

[T]he guarantees you have are laid out by the go memory model, which is well documented [here]. [Specifically, the combination of wg.Done() and wg.Wait() in the example suffices to guarantee non-racy access to the two variables a and b.]



只要存在这个问题,复制 Adrian's comment 可能是个好主意。也:

As @JimB noted, if a value is shared between goroutines, it cannot be stack-allocated, so the question is moot (see How are Go closures layed out in memory?). WaitGroup works correctly.



闭包变量是堆分配的这一事实是一个实现细节:将来可能不是这样。但是 sync.WaitGroup即使 future 一些聪明的 Go 编译器能够将这些变量保存在某个堆栈上,这种保证在 future 仍然是正确的。

(“哪个堆栈?”完全是另一个问题,但假设 future 聪明的 Go 编译器要回答这个问题。 WaitGroup 和内存模型提供了规则。)

关于go - 使用WaitGroup从不同的go例程阻塞当前变量写入堆栈变量是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58954237/

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