当我在goroutine中添加select default语句时,通道发生死锁。

huangapple go评论91阅读模式
英文:

Channel deadlocks when I add select default statement in goroutine

问题

我正在学习通道,并且以下是我尝试的一个测试,但发生了死锁。

func main() {
    ch := make(chan int)
    go func() {
        select {
        case ch <- 1:
            fmt.Println("send suc")
        default: // 如果注释掉这一行,代码将正常运行
            fmt.Println("default")
        }
    }()
    time.Sleep(2) // 做一些耗时的操作...
    fmt.Printf("receive val: %d", <-ch)
}

我原本期望不会发生死锁,但结果是:

default
fatal error: all goroutines are asleep - deadlock!

但是如果我移除 default 或者 time.Sleep(2),代码将正常运行,结果为:

send suc
receive val: 1

有人可以解释一下为什么会发生死锁吗?

英文:

I'm learning channel and below is a test I tried, but deadlock happens

func main() {
    ch := make(chan int)
    go func() {
    	select {
    	case ch &lt;- 1:
        	fmt.Println(&quot;send suc&quot;)
        default: // if comment this line, it will run smoothly
        	fmt.Println(&quot;default&quot;)
    	}
    }()
    time.Sleep(2) // do some time consuming thing...
    fmt.Printf(&quot;receive val: %d&quot;, &lt;-ch)
}

I expected there is no deadlock, but result is:

default
fatal error: all goroutines are asleep - deadlock!

But if I remove default or time.Sleep(2), code will run smoothly, result:

send suc
receive val: 1

Can someone explain why deadlock happen?

答案1

得分: 6

你有一个带有defaultselect语句,这意味着如果没有任何通信操作准备就绪,select 不会等待,不会阻塞,而是立即执行default分支。通道是无缓冲的,因此发送操作不准备就绪(因为没有接收方准备就绪 - main正在休眠)。

因此,一旦main中的休眠结束,它尝试从通道接收数据,但此时没有任何人试图在通道上发送数据。发生了死锁。

英文:

You have a select with default, that means if none of the communication ops are ready, select will not wait, will not block, but execute default immediately. The channel is unbuffered, so the send on it is not ready (because there are no receivers ready – main is sleeping).

So once the sleep is over in main, it tries to receive from the channel, but by then there is nobody trying to send on it. Deadlock.

huangapple
  • 本文由 发表于 2022年11月15日 17:35:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/74443385.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定