dqdfpmmi022763 2016-08-08 03:44
浏览 75
已采纳

在for循环中生成goroutine时出现死锁

Consider the following go playground

package main

import "fmt"

func main() {

    var chan_array [2]chan int

    chan1 := make(chan int)
    chan2 := make(chan int)

    chan_array[0] = chan1
    chan_array[1] = chan2


    for i := 0; i < 2; i++ {
        go func() {

            select {
                case x := <- chan_array[i]:
                    if (x == 0) {
                        return
                    }       
                    fmt.Println(x)
            }
        }()
    }

    chan1<- 1
    chan2<- 2
    chan1<- 0
    chan2<- 0
}

The code above is trying to create 2 running goroutines with that listens to the channel to signal print or close.

But the above code run into dead lock.

I am not exactly sure why

Can someone point out my mistake?

Thanks

  • 写回答

2条回答 默认 最新

  • duanpu5048 2016-08-08 04:04
    关注

    There are some problems:
    What is the value of i when chan_array[i-1] runs:

    for i := 0; i < 2; i++ {
        go func() {
            select {
            case x := <- chan_array[i-1]:
                if x == 0 {
                    return
                }
                fmt.Println(x)
            }
        }()
    }
    

    try this:

    for i := 0; i < 2; i++ {
        go func(i int) { 
            select {
            case x := <-chan_array[i]:
                if x == 0 {
                    return
                }
                fmt.Println(x)
            }
        }(i)
    }
    

    Let's simplify your code (with some corrections):

    package main
    
    import "fmt"
    
    func main() {
        chan1 := make(chan int)
        chan2 := make(chan int)
    
        go routine(chan1)
        go routine(chan2)
    
        chan1 <- 1
        chan2 <- 2
        chan1 <- 0
        chan2 <- 0
    }
    
    func routine(ch chan int) {
        select {
        case x := <-ch:
            if x == 0 {
                return
            }
            fmt.Println(x)
        }
    }
    

    With these:

    chan1 <- 1
    chan2 <- 2
    

    fatal error:

    all goroutines are asleep - deadlock!
    

    your goroutines finished and no goroutines listening to chan1 and chan1 here:

    chan1 <- 0
    chan2 <- 0
    

    Your corrected working sample code is:

    package main
    
    import "fmt"
    
    func main() {
        chan1 := make(chan int)
        chan2 := make(chan int)
    
        go routine(chan1)
        go routine(chan2)
    
        chan1 <- 1
        chan2 <- 2
        chan1 <- 0
        chan2 <- 0
    }
    
    func routine(ch chan int) {
        for {
            select {
            case x := <-ch:
                if x == 0 {
                    return
                }
                fmt.Println(x)
            }
        }
    }
    

    output:

    1
    2
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器