Golang中的复制并发安全吗?

时间:2019-02-20 03:51:53

标签: go concurrency data-race

在某些情况下,我会将一些内容复制到切片的不同部分。 像这样

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)

它领先DATA RACE。但是它在产品环境中总是表现正确。

所以我的问题是:

  1. 任何数据竞赛云都是不确定的行为吗?
  2. 在这样的练习中我能总是得到正确的结果吗?

1 个答案:

答案 0 :(得分:1)

为避免数据争用(结果不确定),请进行同步。例如,

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)
}

游乐场:https://play.golang.org/p/rYCBMV7wuNn

输出:

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

  

Package sync

import "sync"
     

type WaitGroup

     

WaitGroup等待goroutine的集合完成。主要的   goroutine调用添加以设置要等待的goroutine数量。然后   每个goroutine都会运行并在完成后调用Done。在同一时间   时间,可以使用Wait来阻塞,直到所有goroutine完成为止。

     

首次使用后,不得复制WaitGroup。

type WaitGroup struct {
        // contains filtered or unexported fields
}