Безопасно ли параллельное копирование на Голанге? - PullRequest
0 голосов
/ 20 февраля 2019

В некоторых случаях я бы скопировал некоторый контент в другой фрагмент фрагмента.Вот так

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 голосов
/ 20 февраля 2019

Чтобы избежать гонки данных, которая будет иметь неопределенные результаты, синхронизируйте.Например,

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

Группа WaitGroup ожидает завершения сбора программ.Основные вызовы подпрограмм Добавить, чтобы установить количество ожидающих очередей.Затем каждая из программ запускается и вызывает Готово, когда закончите.В то же время, Wait может использоваться для блокировки до завершения всех процедур.

Группа WaitGroup не должна копироваться после первого использования.

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