On Monday, 12 September 2016 12:04:30 UTC-4, sqweek E. wrote: > > Yes, through plain assignment. What problems arise from that? >
Here's the general form of the problem. In the code below, one goroutine (f) creates a variable, initializes it (x=1), then shares its address with another goroutine (in this case by assigning to a global variable, but that's a detail). Another goroutine (g) reads the pointer out of the global variable and inspects the variable to which it points. type T struct { x int } var global *T func f() { p := new(T) p.x = 1 global = p // "publish" the new T (racy!) } func g() { p = global if p != nil { println(p.x) // may print "0" due to data race } } go f() go g() One might naively think that the print statement always prints 1, but in fact it can print 0. The reason is that the compiler or CPU is free to reorder the assignments p.x=1 and global=p, since f can't tell. But reordering means other goroutines might observe a non-nil pointer in global before the thing it points to has been fully initialized. To safely "publish" a variable initialized by one goroutine so that other goroutines see it properly initialized, you need "barrier semantics", that is, you need to tell the compiler and CPU not to reorder those assignments. That's what atomic.Value does. But you shouldn't reach for atomic.Value without data. In most programs, a mutex is simpler to reason about and plenty fast enough. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.