【发布时间】:2021-10-16 10:33:57
【问题描述】:
如果我们在不同的 go co-routines 中访问结构的互斥字段,是否存在任何并发问题?
我记得在某处读到过,如果两个并行线程访问同一个对象,它们可能会在 cpu 的不同内核上运行,这两个内核都具有不同的 cpu 级缓存和所讨论对象的不同副本。 (与 Go 无关)
以下代码是否足以正确实现功能或是否需要使用额外的同步机制?
package main
import (
"fmt"
"sync"
)
type structure struct {
x string
y string
}
func main() {
val := structure{}
wg := new(sync.WaitGroup)
wg.Add(2)
go func1(&val, wg)
go func2(&val, wg)
wg.Wait()
fmt.Println(val)
}
func func1(val *structure, wg *sync.WaitGroup) {
val.x = "Test 1"
wg.Done()
}
func func2(val *structure, wg *sync.WaitGroup) {
val.y = "Test 2"
wg.Done()
}
编辑:-对于那些问为什么不频道的人,不幸的是这不是我正在处理的实际代码。 func 都调用了不同的 api 并在结构中获取数据,这些结构中有一个 pragma.DoNotCopy 询问 protobuf 自动生成器为什么他们认为这是一个好主意。所以这些数据不能通过通道发送,否则我必须创建另一个结构来发送数据或要求 linter 停止抱怨。或者我可以发送一个指向对象的指针,但感觉它也在共享内存。
【问题讨论】:
-
澄清一下,CPU 没有任何对象或结构的概念,这些边界仅存在于您使用的语言中。
-
memory model 描述了需要同步的位置。每个字段都是内存模型中的一个单独变量。
-
为什么不通过渠道使用并发?您能否详细介绍一下问题的背景?
-
这是我正在考虑的具体场景:- main func 创建字段,也许是 cpu1 的 L1 缓存,缓存数据,现在 func1& func2 在 cpu2 上运行,将数据写入这些字段并完成协程.当 main 再次在 cpu1 上运行时,它不会仍然认为它的缓存是正确的数据。基本上是这样的tutorialspoint.com/parallel_computer_architecture/… 或者协程保证在同一个cpu上运行?
标签: go