Модель памяти Go происходит раньше (каналы с общим состоянием) - PullRequest
1 голос
/ 30 сентября 2019

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

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

(Кроме того, очевидный ответ в приведенном ниже примере - поместить экземпляр 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)

1 Ответ

4 голосов
/ 30 сентября 2019

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

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