Тупик с несколькими программами с несколькими каналами - PullRequest
0 голосов
/ 05 ноября 2018

Я работаю над примером программы, чтобы вывести сумму нечетного и четного числа от 1 до 100, используя goroutine с несколькими каналами.

Вы можете найти мой код

здесь

выход

sum of even number = 2550
sum of odd number = 2500
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.print(0x434100, 0x11db7c)
    /tmp/sandbox052575152/main.go:18 +0xc0
main.main()
    /tmp/sandbox052575152/main.go:14 +0x120

Код работает, но с тупиком. Я не уверен, что не так в моем коде

1 Ответ

0 голосов
/ 05 ноября 2018

Мы можем перебирать значения, передаваемые по каналу. Чтобы прервать такую ​​итерацию, канал необходимо явно закрыть. В противном случае диапазон будет блокироваться навсегда так же, как для нулевого канала. В вашем коде вы не закрыли канал sum (для функции печати sumValues канал). Поэтому следующая функция будет заблокирована навсегда.

func print(sumValues <-chan string ){
    for val := range sumValues {
        fmt.Println(val)
    }
}

Таким образом, вы должны закрыть канал sum в функции doSum после завершения всех подпрограмм go в функции doSum (в противном случае канал sum может быть закрыт до завершения подпрограмм go). Вы можете использовать sync.WaitGroup для этого. Смотрите обновленную функцию doSum ниже:

func doSum(sum chan<- string, oddChan <-chan int, evenChan <-chan int) {
    var waitGroup sync.WaitGroup

    waitGroup.Add(2) // Must wait for 2 calls to 'done' before moving on

    go func(sum chan<- string) {
        s1 := 0
        for val := range oddChan {
            s1 += val
        }
        sum <- fmt.Sprint("sum of odd number = ", s1)
        waitGroup.Done()
    }(sum)

    go func(sum chan<- string) {
        s1 := 0
        for val := range evenChan {
            s1 += val
        }
        sum <- fmt.Sprint("sum of even number = ", s1)
        waitGroup.Done()
    }(sum)

    // Waiting for all goroutines to exit
    waitGroup.Wait()

    // all goroutines are complete now close the sum channel
    close(sum)
}
...