Golang中国

看这段代码:

package main

import (
    "fmt"
)

func main() {

    var e int
    ok := true
    ch1 := make(chan int, 10)

    for i := 0; i < len(ch1); i++ {
        ch1 <- 1
    }

    for {
        select {
        case e, ok = <-ch1:
            if !ok {
                fmt.Println("End.")
            } else {
                fmt.Printf("%d\n", e)
            }
        }
        if !ok {
            break
        }
    }
}

为什么会死锁啊?

7 回复
xyz
#1 xyz • 2016-12-25 20:16

ch1 := make(chan int, 10)
len(ch1) = 0
cap(ch1)=10

case e, ok = <-ch1: 当len(ch1)=0时,会把当前的协程切出去,这个只有main,没有可运行的协程,所以会死锁。

package main

import (
    "fmt"
)

func main() {
    var e int
    ch1 := make(chan int, 10)
    for i := 0; i < cap(ch1); i++ {
        ch1 <- 1
    }
    for {
        select {
        case e = <-ch1:
            fmt.Printf("%d\n", e)
        default:
            fmt.Println("End.")
            return
        }

    }
}
samete
#2 samete • 2016-12-25 21:11

case e, ok = <-ch1: 当len(ch1)=0时,会把当前的协程切出去,这个只有main,没有可运行的协程,所以会死锁。
你是指这个协程就是主协程?

samete
#3 samete • 2016-12-26 11:08

我把代码改成这样:

package main

import (
    "fmt"
)

func main() {

    ch1 := make(chan int, 10)

    // fmt.Println(len(ch1), cap(ch1))
    for i := 0; i < cap(ch1); i++ {
        ch1 <- i
    }
    // fmt.Println(len(ch1), cap(ch1))

    for j := 0; j < len(ch1); j++ {
        c := <-ch1
        fmt.Println(c)
    }

}

为什么打印的结果是0 1 2 3 4 ?

xyz
#4 xyz • 2016-12-27 10:59

case e, ok = <-ch1: 当len(ch1)=0时,会把当前的协程切出去,这个只有main,没有可运行的协程,所以会死锁。
你是指这个协程就是主协程?
是的

samete
#5 samete • 2016-12-27 11:33

thanks,我知道为什么了,谢谢啊!

fanyang
#6 fanyang • 2016-12-27 15:38

Q:为什么打印的结果是0 1 2 3 4 ?
A:c := <-ch1每次从通道里取出一个数,len(ch1)就会减1,当j=5, len(ch1)=5

samete
#7 samete • 2016-12-27 16:34

嗯,知道了,谢谢!

需要 登录 后方可回复, 如果你还没有账号你可以 注册 一个帐号。

作者

发表话题

作者其它话题