Проблема с golang параллелизмом за один раз - PullRequest
0 голосов
/ 05 марта 2020

Я читаю официальный документ, есть код, который я не могу понять.

var a string
var done bool

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        once.Do(setup)
    }
    print(a)
}

func twoprint() {
    go doprint()
    go doprint()
}

Эта версия может (неправильно) печатать пустую строку вместо слова "привет, мир" .

Почему этот код может давать неправильные результаты.

1 Ответ

3 голосов
/ 05 марта 2020

Поскольку в doprint() переменная done доступна (считывается) без синхронизации.

Представьте себе, что первый запуск процедуры doprint() завершается до того, как запланирован запуск второй. Первый пишет donesetup()), а 2-ая программа пытается прочитать done: должно ли это чтение дать результат, написанный первой программой? Синхронизация отсутствует: неопределенное поведение. Может случиться так, что done будет наблюдаться как true, и, таким образом, setup() не будет вызван, и это может быть запись в a не будет наблюдаться, и, таким образом, начальное нулевое значение (пустая строка) напечатано.

При чтении переменных всегда наблюдаются предыдущие записи (предыдущие по времени) в процедуре single . Не гарантируется, что записи, сделанные goroutine, будут выполняться в другой goroutine, если между ними нет синхронизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...