Question

Is it safe to access the same array from multiple goroutines, when every goroutine works on a slice, pointing to the same underlying array but without overlapping ?

Like:

var arr [100]int
sliceA := arr[:50]
sliceB := arr[50:]

go WorkOn(sliceA)
go WorkOn(sliceB)

Just imagine "WorkOn" would do something fancy.

Was it helpful?

Solution

As long as you can guarantee the areas won't overlap, it's fine.

By guarantee I mean: whomever works on sliceA, should not be allowed to do sliceA = append(sliceA, a, b, c). Because then it'll start running into sliceB's territory.

Relevant here, is some documentation for Go 1.2: This concerns a new language element: 3-index slices:

Go 1.2 adds the ability to specify the capacity as well as the length when using a slicing operation on an existing array or slice. A slicing operation creates a new slice by describing a contiguous section of an already-created array or slice:

var array [10]int
slice := array[2:4]

The capacity of the slice is the maximum number of elements that the slice may hold, even after reslicing; it reflects the size of the underlying array. In this example, the capacity of the slice variable is 8.

Go 1.2 adds new syntax to allow a slicing operation to specify the capacity as well as the length. A second colon introduces the capacity value, which must be less than or equal to the capacity of the source slice or array, adjusted for the origin. For instance,

slice = array[2:4:7]

sets the slice to have the same length as in the earlier example but its capacity is now only 5 elements (7-2). It is impossible to use this new slice value to access the last three elements of the original array.

In this three-index notation, a missing first index ([:i:j]) defaults to zero but the other two indices must always be specified explicitly. It is possible that future releases of Go may introduce default values for these indices.

Further details are in the design document.

OTHER TIPS

Actually jimt's answer MAY be wrong. It depends... :)

E.g. if you are using a []uint8, then a operation like

p[2] = 5

is essentially this

tmp = p[0..3] // this is 32 bit
tmp[2] = 5
p[0..3] = tmp // yeah this is all fake syntax but you'll get it

This is because your CPU is 32 (or even 64) bit. So that is actually more efficient although it seems more complex.

But as you can see, you are WRITING p[0,1,3] although you only intended to write to p[2]. This can create some fun bugs to debug! :)

If your data is e.g. pointers to your data then this issue should not occur as arrays are guaranteed to be stored in memory so that this problem doesn't occur as long as your data is as long as your native instruction set.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top