У меня странное состояние гонки. Проблема в том, что это происходит внутри объекта, который еще не существует.
Вот демонстрационный код:
package main
import (
//"fmt"
"time"
)
type Object1 struct {
A int
B string
C []int
D *Object2
}
type Object2 struct {
A int
}
func NewObject1() *Object1 {
return &Object1{
A: 1,
B: "abc",
C: []int{0, 1},
D: &Object2{},
}
}
func main() {
list := []*Object1{}
tempA := 0
tempB := ""
tempC := []int{}
tempD := &Object2{}
go func() {
for {
for _, object := range list {
tempA = object.A
tempB = object.B
tempC = object.C
tempD = object.D
}
}
}()
for {
list = append(list, NewObject1())
//fmt.Println("list", list)
time.Sleep(1 * time.Second)
}
}
Если я запускаю его с флагом -race
- я получаю предупреждения:
WARNING: DATA RACE
Read at 0x00c000094040 by goroutine 5:
main.main.func1()
/tmp/race.go:39 +0x84
Previous write at 0x00c000094040 by main goroutine:
main.main()
/tmp/race.go:21 +0x2a9
Goroutine 5 (running) created at:
main.main()
/tmp/race.go:36 +0x276
==================
==================
WARNING: DATA RACE
Read at 0x00c000094048 by goroutine 5:
main.main.func1()
/tmp/race.go:40 +0xbe
Previous write at 0x00c000094048 by main goroutine:
main.main()
/tmp/race.go:22 +0x2ca
Goroutine 5 (running) created at:
main.main()
/tmp/race.go:36 +0x276
==================
==================
WARNING: DATA RACE
Read at 0x00c000094058 by goroutine 5:
main.main.func1()
/tmp/race.go:41 +0x118
Previous write at 0x00c000094058 by main goroutine:
main.main()
/tmp/race.go:23 +0x341
Goroutine 5 (running) created at:
main.main()
/tmp/race.go:36 +0x276
==================
==================
WARNING: DATA RACE
Read at 0x00c000094070 by goroutine 5:
main.main.func1()
/tmp/race.go:42 +0x180
Previous write at 0x00c000094070 by main goroutine:
main.main()
/tmp/race.go:24 +0x3b8
Goroutine 5 (running) created at:
main.main()
/tmp/race.go:36 +0x276
==================
Но как это возможно? Чтение происходит внутри goroutine и запись внутри NewObject1()
. 4 ошибки для каждого поля Object1
. NewObject1()
еще не создал объект, чтобы добавить его к срезу list
. Так что list
во время чтения должен быть пустым или заполняться нормально завершенными объектами.
Шаг за шагом, рабочий процесс в моей голове:
- список пуст;
- вы начинаете создавать новые
object1
;
- список еще пуст;
- вы создали новый объект и только потом добавляете его в список;
- только теперь в списке есть 1 элемент;
- чтение происходит.
Я не вижу здесь состояния гонки. Если вы думаете иначе - пожалуйста, покажите свой собственный рабочий процесс, как все происходит.