-1

In some circumstance, i would copy some content to different piece of the slice. Like this

a := make([]int, 10)
for i := 0; i < 10; i++ {
    b := []int{i}
    go func(i int) {
        copy(a[i:i+1], b)
    }(i)
}
time.Sleep(time.Second)
fmt.Println(a)

It leads DATA RACE. But it always behave right in product environment.

So my question is:

  1. Any data race cloud be undefined behavior?
  2. Can i always get right result in such a practice?
HolaYang
  • 419
  • 2
  • 10
  • 2
    No. Nothing is concurrency safe unless explicitly stated (e.g. channel ops in the Memeory Model) and data races **must** be avoided: A program with a data race is wrong and may produce wrong results at any time. – Volker Feb 20 '19 at 05:41

1 Answers1

1

To avoid the data race, which will have undefined results, synchronize. For example,

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    a := make([]int, 10)
    for i := 0; i < 10; i++ {
        b := []int{i}
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            copy(a[i:i+1], b)
        }(i)
    }
    wg.Wait()
    fmt.Println(a)
}

Playground: https://play.golang.org/p/rYCBMV7wuNn

Output:

$ go run -race norace.go
[0 1 2 3 4 5 6 7 8 9]
$

Package sync

import "sync"

type WaitGroup

A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. At the same time, Wait can be used to block until all goroutines have finished.

A WaitGroup must not be copied after first use.

type WaitGroup struct {
        // contains filtered or unexported fields
}
peterSO
  • 158,998
  • 31
  • 281
  • 276
  • Thanks a lot. I was trapped in some misunderstanding, in my mind, doing multi `copy` concurrently cause `data race`. I got it from your answer. – HolaYang Feb 20 '19 at 07:31