2015-09-20 2 views
1

Как получилось, что-то простое, как это, не работает?Ошибка при получении: все goroutines спали - deadlock

c1 := make(chan string) 
c1 <- "foo" 
fmt.Println(<-c1) 

Но если я положу его в рутину, это сработает?

c1 := make(chan string) 
go func() { 
    c1 <- "foo" 
}() 
fmt.Println(<-c1) 

Вопрос может показаться простым и глупым, но я пытаюсь понять, почему я не могу это сделать, и я не знаю ничего лучше спросить в этом случае.

ответ

7

Канал c1 - это канал unbuffered. Связь выполняется небуферизованным каналом только тогда, когда и отправитель, и приемник готовы.

Строка c1 <- "foo блокируется навсегда, потому что приемник не готов.

Программа с goroutine работает, потому что отправляющие и принимающие goroutines работают до той точки, где отправитель и получатель готовы.

Эта программа также будет работать:

c2 := make(chan string, 1) // <-- note channel size of one 
c2 <- "foo" 
fmt.Println(<-c2) 

канал c2 буферизуется в этой программе. Отправка c2 <- "foo" продолжается, потому что буфер не заполнен.

+0

Спасибо! Это было очень полезно! – Alex