Модель Go Memory происходит раньше (каналы с общим состоянием)

Я пытаюсь более полно понять природу отношений Happens-Before между каналами и другим общим состоянием. В частности, я хочу посмотреть, создается ли какое-либо ограждение памяти при операции отправки и получения канала.

Например, если я отправляю сообщение по каналу, все остальные операции, связанные с изменением общего состояния, выполняются «до» операции отправки/получения. В моем конкретном примере я пишу только из одной процедуры go, а затем читаю из одной процедуры go.

(Кроме того, очевидный ответ в приведенном ниже примере — поместить экземпляр структуры Person непосредственно в канал, но это не то, о чем я прошу.)

package main

func main() {
    channel := make(chan int, 128)

    go func() {
        person := &sharedState[0]
        person.Name = "Hello, World!"
        channel <- 0
    }()

    index := <-channel
    person := sharedState[index]
    if person.Name != "Hello, World!" {
        // unintended race condition
    }
}

type Person struct{ Name string }

var sharedState = make([]Person, 1024)

person Jonathan Oliver    schedule 30.09.2019    source источник


Ответы (1)


Модель памяти гарантирует, что при выполнении операции записи в канал все операции в этой горутине, предшествующие операции в канале, будут видны. Таким образом, в вашем примере «непреднамеренное состояние гонки» не может произойти, потому что при чтении канала становится видимым назначение, произошедшее в горутине. Это, конечно, предполагает, что нет другой горутины, которая записывает ту же самую переменную. Если бы была другая горутина, записывающая ту же самую переменную, вам также нужно было бы синхронизировать эту горутину, чтобы избежать гонки.

person Burak Serdar    schedule 30.09.2019
comment
Я то же искал. В документации они не упоминают ДРУГИЕ операции, которые происходят до того, как запись будет видна в другом потоке после чтения, они просто говорят конкретно об операциях канала. Не могли бы вы указать, где это упоминается. - person shota silagadze; 27.01.2020
comment
и является ли эта гарантия такой же для мьютексов? - person shota silagadze; 27.01.2020
comment
@shotasilagadze golang.org/ref/mem#tmp_8 рассказывает о мьютексах. В следующем разделе рассказывается о sync.Once. Функции пакета sync/atomic также предлагают некоторые гарантии, и было несколько дискуссий о добавлении их в модель памяти. Об этом обсуждается проблема на github, у меня нет ссылки на банкомат. - person Burak Serdar; 27.01.2020