goroutines 中的死锁

Dead lock in goroutines

谁能给我一些关于这段代码的见解,为什么这会在 for x:=range c

中出现死锁错误
func main() {
    c:=make(chan int,10)

    for i:=0;i<5;i++{
        go func(chanel chan int,i int){
            println("i",i)
            chanel <- 1
        }(c,i)
    }

    for x:=range c {
        println(x)
    }
    println("Done!")
}

因为这个:

    for x:=range c {
        println(x)
    }

将循环播放直到频道 c 关闭,这在此处从未完成。

这里有一种方法可以修复它,使用 WaitGroup:

package main

import "sync"

func main() {
    var wg sync.WaitGroup
    c := make(chan int, 10)

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(chanel chan int, i int) {
            defer wg.Done()
            println("i", i)
            chanel <- 1
        }(c, i)
    }

    go func() {
        wg.Wait()
        close(c)
    }()

    for x := range c {
        println(x)
    }
    println("Done!")
}

Try it on Go Playground

您创建了五个 goroutine,每个 goroutine 都向通道发送一个整数值。写入所有这五个值后,就没有其他 goroutine 写入通道了。

主协程从通道中读取这五个值。但是没有 goroutines 可以写入第六个值或关闭通道。因此,您在等待来自通道的数据时陷入僵局。

所有写入完成后关闭通道。找出如何使用此代码执行此操作应该是一个有趣的练习。

需要关闭频道以指示任务已完成。

坐标 sync.WaitGroup:

c := make(chan int, 10)

var wg sync.WaitGroup // here

for i := 0; i < 5; i++ {

    wg.Add(1) // here

    go func(chanel chan int, i int) {
        defer wg.Done()
        println("i", i)
        chanel <- 1
    }(c, i)
}

go func() {
    wg.Wait() // and here
    close(c)
}()

for x := range c {
    println(x)
}
println("Done!")

https://play.golang.org/p/VWcBC2YGLvM