-1

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

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. 在这样的练习中,我总能得到正确的结果吗?
4

1 回答 1

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]
$

包同步

import "sync"

输入等待组

WaitGroup 等待一组 goroutine 完成。主 goroutine 调用 Add 来设置要等待的 goroutine 的数量。然后每个 goroutine 运行并在完成时调用 Done。同时,Wait 可以用来阻塞,直到所有的 goroutine 都完成。

首次使用后不得复制 WaitGroup。

type WaitGroup struct {
        // contains filtered or unexported fields
}
于 2019-02-20T04:10:26.827 回答