Вопрос:

Тупик между горутинами

go goroutine

74 просмотра

2 ответа

109 Репутация автора

Я новичок в Go. Когда я комментирую вторую программу, возникает фатальная ошибка. Я не понимаю, что вызывает эту ошибку. Можете ли вы объяснить это мне?

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)
    go func() { 
        for i := 0; i < 10; i++ {
            ch <- i
        }
    } ()
    // go func() { 
        for {
            if num, ok := <-ch; !ok {
                break
            } else {
                fmt.Printf("%d\n", num)
            }
        }
    // } ()
    time.Sleep(2 * time.Second)
    close(ch)
}

Это печатает следующий код:

0
1
2
3
4
5
6
7
8
9
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    /tmp/sandbox169127128/main.go:17 +0xa0

Program exited.
Автор: Pizzas Источник Размещён: 08.04.2017 04:22

Ответы (2)


5 плюса

62642 Репутация автора

Решение

Получение для циклических блоков при получении от chпосле получения всех значений из отправляющей программы. Среда выполнения обнаруживает, что программа застряла и паникует.

Исправление - закрыть канал после отправки всех значений:

go func() { 
    for i := 0; i < 10; i++ {
        ch <- i
    }
    close(ch)
} ()

Прием по закрытому каналу дает значение 0, false. Получение для прерываний цикла на ложное значение.

Удалить close(ch)из конца программы.

Запустите его на детской площадке .

Автор: Cerise Limón Размещён: 08.04.2017 04:31

2 плюса

2371 Репутация автора

Потому что вы не закрываете канал перед первым выходом из программы. Код ниже должен работать.

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int)
    go func() { 
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
    } ()
    //go func() { 
        for {
            if num, ok := <-ch; !ok {
                break
            } else {
                fmt.Printf("%d\n", num)
            }
        }
    //} ()
    time.Sleep(2 * time.Second)
}

Попробуйте это здесь: https://play.golang.org/p/OdxNqbaZmj

Автор: RaviTezu Размещён: 08.04.2017 04:34
Вопросы из категории :
32x32