On Thu, Aug 03, 2017 at 07:21:24AM +0000, Henrik Johansson wrote: [...] > It gets hypothetical pretty quick and usually when this happens I make sure > to create a new array/slice/whatever and then atomically swap it before > some other goroutine uses it but I generally avoid indexing assignment from > go routines like this even though it seems to be ok. > > Does this hold for slices as well as for arrays? What about assignments to > fields in structs? Can several goroutines safely write to different fields > in the same struct assuming they are word sized? Does this hold for all > architectures? [...]
>From past discussions on this list, I gathered that two facts should be considered when reasoning about the conditions ... 1) When Go memory model discusses happens-before relationships between concurrently executing goroutines, it talks about *variables* operated on by those goroutines. This is sort of logical since Go does not allow access to arbitrary memory locations (as you could do in C, for instance): any writes and reads happen on variables. To cite the memory model document [1]: | The Go memory model specifies the conditions under which reads of a | variable in one goroutine can be guaranteed to observe values produced | by writes to the same variable in a different goroutine. 2) The Go language spec again talks about variables when it discusses types, and a crucial point of that discussion is that *structured* types are defined to behave like compositions of variables. To cite the spec: | A variable is a storage location for holding a value. The set of | permissible values is determined by the variable's type. | <...> | Structured variables of array, slice, and struct types have elements and | fields that may be addressed individually. Each such element acts like a | variable. To provide a slighly different view: a variable is a (typed) memory location which is addressable. That's why invididual elements of arrays and slices are variables, and fields of the values of struct types are values, too, but the elements of maps are not: they are not addressable. Of course, certain caveats apply. For instance, a slice itself (the descriptor which contains the pointer to the underlying array, the length and the capacity) stored in a variable can be modified concurrently with any element of that slice without breaking the memory model rules, but the question of whether that would be a sensible superposition of operations is moot. Another example is modifying a variable containing a pointer to some variable of a struct type concurrently with the pointed-to value: this is not against the memory model but may be nonsensical from the point of view of the desired outcome of the program. Hope that helps. -- 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.