некоторые вопросы о канале Голанга - PullRequest
2 голосов
/ 04 октября 2019

Я смотрю видео на YouTube, в котором говорится о шаблонах параллелизма. Вот пример пинг-понга:

type Ball struct{ hits int }
func main() {
    table := make(chan *Ball)
    go player("ping", table)
    go player("pong", table)

    table <- new(Ball)
    time.Sleep(1 * time.Second)
    <-table
}

func player(name string, table chan *Ball) {
    for {
        ball := <-table
        ball.hits++
        fmt.Println(name, ball.hits)
        time.Sleep(100 * time.Millisecond)
        table <- ball
    }
}

, который должен дать результат:

Ping 1
Pong 2
Ping 3
Pong 4
...

Однако, если я удалю одну программу игрока, "pong", например:

// go player("pong", table) // remove this line

Я получил только один результат:

Ping 1

Я не понимаю, что в func-плеере есть цикл for, а канал 'table' выдает Ball на шар, вВ конце цикла мы помещаем мяч обратно в таблицу каналов. Почему игрок «пинг» не может играть сам с собой?

1 Ответ

5 голосов
/ 04 октября 2019

Канал не буферизован, что означает, что одна подпрограмма должна быть получена для завершения отправки другой подпрограммы. Если вы удалите проигрыватель pong, проигрыватель ping заблокируется отправкой по каналу (pong не может получить), поэтому он никогда не перейдет к следующей итерации цикла для получения своего собственного сообщения.

Если вы сделаете канал буферизованным, отправка будет неблокируемой, если в буфере есть место: table := make(chan *Ball, 1). Это позволит удерживать один шарик в буфере канала до тех пор, пока приемник не будет готов.

...