为了账号安全,请及时绑定邮箱和手机立即绑定

goroutine 中的死锁

goroutine 中的死锁

Go
四季花海 2023-08-07 14:37:46
有人可以给我一些关于这段代码的见解,为什么会出现死锁错误for x:=range cfunc 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!")}
查看完整描述

3 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

因为这:


    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!")

}

在 Go Playground 上尝试一下


查看完整回答
反对 回复 2023-08-07
?
潇湘沐

TA贡献1816条经验 获得超6个赞

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

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

所有写入完成后关闭通道。弄清楚如何使用这段代码来做到这一点应该是一个有趣的练习。


查看完整回答
反对 回复 2023-08-07
?
GCT1015

TA贡献1827条经验 获得超4个赞

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


与a协调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


查看完整回答
反对 回复 2023-08-07
  • 3 回答
  • 0 关注
  • 137 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信