Are slices in Go thread-safe? Is it possible to write to different indices of a slice in parallel without a mutex?
sobes.tech AI
Answer from AI
Slices in Go are not inherently thread-safe. This is because a slice is a structure containing a pointer to an array, a length, and a capacity. Concurrent access to different indices of a slice without synchronization can lead to data races if the structure of the slice is modified simultaneously (for example, expanding the slice, changing its length).
If you guarantee that the slice does not change its length and capacity, and you write to different, non-overlapping indices concurrently, then in theory it is safe, as different elements of the array are different memory areas. However, this requires strict control and understanding that no one modifies the slice (for example, calling append).
In summary:
- Reading and writing to different indices of the array referenced by the slice can be safe without a mutex if the length and capacity do not change.
- Any operations that modify the structure of the slice (append, slicing, changing length) require synchronization.
- For guaranteed thread safety, it is better to use mutexes or other synchronization mechanisms.
Example of safe concurrent writing to different indices of an array:
package main
import (
"fmt"
"sync"
)
func main() {
arr := make([]int, 10)
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
arr[i] = i * i // safe, different indices
}(i)
}
wg.Wait()
fmt.Println(arr)
}
But if you change the length of the slice or do an append, races are possible without synchronization.