golang все горутины спят - тупик - PullRequest
0 голосов
/ 04 апреля 2020

Я получил ошибку при запуске, следуя golang сниппету. Я думаю, что прогресс будет блокироваться в wg.Wait () до тех пор, пока не закончится процедура go. тогда значение будет получено из c1. Но это может происходить не так, как ожидалось.

func main() {

c1 := make(chan string)
//var c1 chan string
var wg sync.WaitGroup

wg.Add(1)
go func() {
    defer wg.Done()
    fmt.Printf("go routine begin\n")
    time.Sleep(1 * time.Second)
    c1 <- "one"
    fmt.Printf("go routine done\n")
}()
wg.Wait()
fmt.Printf("done c1: %v\n", <-c1)
fmt.Printf("out\n")
}

информация об ошибке:

 go routine begin
 fatal error: all goroutines are asleep - deadlock!

Ответы [ 3 ]

1 голос
/ 04 апреля 2020

Запись в c1 никогда не будет выполнена, потому что чтение из c1 происходит после wg.Wait(), которое остановится до тех пор, пока c1 не будет записано. Таким образом, основная процедура ожидает на wg.Wait(), а вложенная процедура ожидает на c1 записи.

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

0 голосов
/ 05 апреля 2020

В вашем коде вы используете небуферизованный канал, который блокируется, пока получатель не получит "один". В этом случае код не go после wg.Wait (), потому что wg.Done () никогда не выполняется.

Я думаю, что это то, что вам нужно.

func main() {

c1 := make(chan string)
//var c1 chan string

go func() {
    fmt.Printf("go routine begin\n")
    time.Sleep(1 * time.Second)
    c1 <- "one"
    fmt.Printf("go routine done\n")
}()
fmt.Printf("done c1: %v\n", <-c1)
fmt.Printf("out\n")
}
0 голосов
/ 04 апреля 2020

В Golang операции записи на небуферизованном канале блокируются. Это ясно из документации.

Ваше выполнение заблокировано на

c1 <- "one"

Отложенный оператор

defer wg.Done()

никогда не выполняется.

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