Проблема не в оптимизации компилятора Go, а скорее в отсутствии синхронизации. Присваивание i не сопровождается каким-либо событием синхронизации, поэтому не гарантируется, что оно будет замечено какой-либо другой горутиной. Фактически, агрессивный компилятор может удалить весь оператор i.
Модель памяти Go
Модель памяти Go определяет условия, при которых считывается переменная в одном goroutine может гарантированно наблюдать за значениями, полученными при записи в одну и ту же переменную в другой goroutine.
Чтобы сериализовать доступ, защитите данные с помощью операций с каналом или других примитивов синхронизации. например, в пакетах sync и sync/atomic.
Если вам необходимо прочитать остальную часть этого документа, чтобы понять поведение вашей программы, вы слишком умны. Не умничайте.
Синхронизация
В следующем примере за присвоением a не следует какое-либо событие синхронизации, поэтому не гарантируется, что оно будет соблюдено. любой другой горутиной. Фактически, агрессивный компилятор может удалить весь оператор go.
var a string
func hello() {
go func() { a = "hello" }()
print(a)
}
В следующем примере показано, как сериализовать доступ к i с помощью sync.Mutex.
package main
import (
"sync"
"time"
)
func main() {
mx := new(sync.Mutex)
i := 1
go func() {
for {
mx.Lock()
i
mx.Unlock()
}
}()
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3