Home >Backend Development >Golang >Why is Appending to a Slice in Concurrent Goroutines Not Thread-Safe?

Why is Appending to a Slice in Concurrent Goroutines Not Thread-Safe?

Linda Hamilton
Linda HamiltonOriginal
2024-11-10 00:49:02771browse

Why is Appending to a Slice in Concurrent Goroutines Not Thread-Safe?

Concurrent Slices: Append Not Thread-Safe

Question:

Consider the following code that appends to a slice using multiple goroutines within a for loop:

destSlice := make([]myClass, 0)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        destSlice = append(destSlice, tmpObj)
    }(myObject)
}
wg.Wait()

On occassion, this code produces missing or blank data in destSlice or doesn't include all elements from sourceSlice. Why might this be occurring?

Answer:

In Go, all values are susceptible to data races when subject to concurrent read/write operations, including slices. This is due to the way that slice headers (which contain the information about the capacity and length of the slice) are implemented.

Running the code with the -race flag will confirm the presence of data races:

go run -race play.go

Solution:

To avoid data races and ensure concurrent safety when appending to a slice, a synchronization primitive such as a sync.Mutex should be used to guard the writing of the destSlice value:

var (
    mu        = &sync.Mutex{}
    destSlice = make([]myClass, 0)
)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        mu.Lock()
        destSlice = append(destSlice, tmpObj)
        mu.Unlock()
    }(myObject)
}
wg.Wait()

Alternatively, consider using channels to facilitate the concurrent appending process.

The above is the detailed content of Why is Appending to a Slice in Concurrent Goroutines Not Thread-Safe?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn