блокировка каналов Голанга перед получением значений - PullRequest
0 голосов
/ 24 января 2019

Я не понимаю, почему это не работает https://play.golang.org/p/_ALPii0pXV6, но это https://play.golang.org/p/vCOjAr-o54e работает.

Насколько я понимаю, goroutine асинхронно отправляет значение true в a и 12 в b. Находясь в основной функции, a блокируется, пока не получит значение. Почему, когда я переставляю его, чтобы b был заблокирован перед a, это приводит к тупику?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Перейти к примеру объясняет , что по умолчанию отправка и получение канала ожидают, пока подпрограмма отправки и процедура приема не будут готовы.Эта блокировка становится очевидной с помощью следующего примера :

func main() {
    ch := make(chan int)
    ch <- 1
    fmt.Println(<-ch)
}

Этот код приводит к взаимоблокировке, потому что единственная процедура (основная) застряла на ch <- 1, ожидая другогогорутин, чтобы получить.Мало ли он знает, что мы ожидаем, что он будет получателем на следующей строке.

Это объясняет, почему ваш первый пример не работает, потому что другая программа не отправляет на b до своей операции отправкина a завершено.Но основная процедура не будет получена на a, пока она не будет получена на b!Так что оба застряли в ожидании навсегда.

Чтобы узнать больше об этом виде операции (называемой синхронной операцией), посмотрите это объяснение .

0 голосов
/ 24 января 2019

Каналы Go по умолчанию не буферизированы. Это означает, что он не может отправить по каналу, пока получатель не читает канал. Это на самом деле предпочтительный режим Go. В большинстве случаев он более эффективен, чем буферизованные каналы.

Что означает для вашего первого кода, что программа не может продолжить запись в канал b, пока не завершит запись в канал a. Это не может быть сделано до тех пор, пока основная программа не покажет a.

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