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 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥15 (关键词-阻抗匹配,HFSS,RFID标签天线)
  • ¥15 机器人轨迹规划相关问题
  • ¥15 word样式右侧翻页键消失