Функция добавления: не потокобезопасна для одновременного доступа
При одновременном использовании горутин для добавления элементов в срез внутри цикла for возникают аномалии в данных может возникнуть. В результирующем срезе могут появиться отсутствующие или пустые данные, что указывает на потенциальную гонку данных.
Это происходит потому, что в Go ни одно значение не является изначально безопасным для одновременного чтения и записи. Срезы, представленные заголовками срезов, не являются исключением. В предоставленном коде наблюдаются гонки данных из-за одновременного доступа:
destSlice := make([]myClass, 0) var wg sync.WaitGroup for _, myObject := range sourceSlice { wg.Add(1) go func(closureMyObject myClass) { defer wg.Done() var tmpObj myClass tmpObj.AttributeName = closureMyObject.AttributeName destSlice = append(destSlice, tmpObj) }(myObject) } wg.Wait()
Чтобы проверить наличие состязаний в данных, выполните следующую команду:
go run -race play.go
Вывод предупредит вас о наличии данных расы:
WARNING: DATA RACE ...
Решение проблем параллелизма
Чтобы решить эту проблему, защитите доступ на запись к destSlice, используя sync.Mutex:
var ( mu = &sync.Mutex{} destSlice = make([]myClass, 0) ) var wg sync.WaitGroup for _, myObject := range sourceSlice { wg.Add(1) go func(closureMyObject myClass) { defer wg.Done() var tmpObj myClass tmpObj.AttributeName = closureMyObject.AttributeName mu.Lock() destSlice = append(destSlice, tmpObj) mu.Unlock() }(myObject) } wg.Wait()
В качестве альтернативы рассмотрите возможность использования канала для асинхронной обработки добавлений:
var ( appendChan = make(chan myClass) destSlice = make([]myClass, 0) ) var wg sync.WaitGroup for _, myObject := range sourceSlice { wg.Add(1) go func(closureMyObject myClass) { defer wg.Done() var tmpObj myClass tmpObj.AttributeName = closureMyObject.AttributeName appendChan
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3