使用for循环遍历通道时获取Goroutine死锁

时间:2019-06-24 20:07:00

标签: go channel goroutine

我正尝试练习goroutine和频道,在这里我遇到的问题是我正在调用gorouting和pass频道。 goroutine将数据推入通道,然后主线程将打印元素。

我已经使用for循环来打印内容但得到了。

fatal error: all goroutines are asleep - deadlock!

2
1
goroutine 1 [chan receive]:
main.main()
package main

import "fmt"


func smallThread(a int, c chan int) {
    c <- a
}

func main() {
    c := make(chan int)
    go smallThread(1, c)
    go smallThread(2, c)
    for {
        fmt.Println(<-c)
    }
}

编辑: 使用waitgroup:

func smallThread(a int, c chan int, w *sync.WaitGroup) {
    c <- a
    w.Done()
}

func main() {
    c := make(chan int)
    var w sync.WaitGroup
    w.Add(2)
    go smallThread(1, c, &w)
    go smallThread(2, c, &w)
    //w.Wait()
    for i := range c {
        fmt.Println(i)
    }
    w.Wait()
}

EDIT2 :工作代码

func smallThread(a int, c chan int, w *sync.WaitGroup) {
    //defer w.Done()
    c <- a
    w.Done()
}

func main() {
    c := make(chan int)
    var w sync.WaitGroup
    w.Add(1)
    go smallThread(1, c, &w)
    w.Add(1)
    go smallThread(2, c, &w)
    go func(c chan int) {
        for i := range c {
            fmt.Println(i)
        }
    }(c)
    w.Wait()
}

2 个答案:

答案 0 :(得分:1)

当goroutine完成后,关闭通道以指示将不再添加任何值。收到所有值后,for循环将中断。

c := make(chan int)
var w sync.WaitGroup
w.Add(2)
go smallThread(1, c, &w)
go smallThread(2, c, &w)
go func() {
    w.Wait()
    close(c)
}()

for i := range c {
    fmt.Println(i)
}

答案 1 :(得分:0)

不确定您的问题是什么,但是我会告诉您发生了什么。您的两个侧面goroutine将其编号推入通道并退出。然后,主goroutine(此时仅剩一个)将永远阻塞,等待另一个元素从通道中出来。