«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Почему моя горутина, увеличивающая переменную, дает неожиданные результаты?

Почему моя горутина, увеличивающая переменную, дает неожиданные результаты?

Опубликовано 5 ноября 2024 г.
Просматривать:295

Why Does My Goroutine Incrementing a Variable Produce Unexpected Results?

Это результат оптимизации компилятора?

В этом фрагменте кода запускается горутина, которая многократно увеличивает переменную i:

package main

import "time"

func main() {
    i := 1
    go func() {
        for {
            i  
        }
    }()
    

Однако результат всегда равен 1. Такое поведение можно отнести к модели памяти Go и конкретной реализации этого кода.

Модель памяти Go

The Модель памяти Go определяет условия, при которых при чтении переменной в одной горутине можно гарантированно наблюдать значения, полученные при записи в ту же переменную в другой горутине. Он подчеркивает важность синхронизации для одновременного доступа к общим данным.

Пропуск синхронизации

В данном коде:

  • Присваивание i (т.е. i ) не сопровождается каким-либо событием синхронизации, что указывает на то, что изменения могут быть не сразу видны другим горутинам.
  • Компилятор может оптимизировать эту оптимизацию цикла, упростив ее до неактивного режима.

Оптимизация компилятором

Агрессивный компилятор может удалить оператор i, эффективно сокращая горутину до:

for {}

Пример с синхронизацией

Чтобы продемонстрировать, что проблема связана с отсутствием синхронизации, рассмотрим следующий код:

package main

import (
    "sync"
    "time"
)

func main() {
    mx := new(sync.Mutex)
    i := 1
    go func() {
        for {
            mx.Lock()
            i  
            mx.Unlock()
        }
    }()
    

В этом случае на выходе будет уже не 1, а большое число, как и ожидалось. sync.Mutex обеспечивает синхронизацию и гарантирует, что обе горутины получают контролируемый доступ к i, позволяя горутине увеличивать i и делая изменения видимыми для основной подпрограммы.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3