【问题标题】:Why does chan not deadlock in goroution?为什么chan不会在goroution中陷入僵局?
【发布时间】:2018-06-08 12:56:30
【问题描述】:
package main
func main() {
    ch1 := make(chan int)
    go pump(ch1) // pump hangs
}
func pump(ch chan int) {
    ch <- 1
    ch <- 2
}

为什么写一个损坏没有错?阻塞主进程会死锁

【问题讨论】:

  • 没有阻塞主协程,没有死锁。
  • 正如之前的评论指出的那样,程序不会死锁 (test it here)。如果您的实际代码中存在死锁,请编辑问题以包含该代码。

标签: go goroutine


【解决方案1】:

因为 main() 函数退出并终止程序,而 pump() 协程被阻止写入通道。

我认为这段代码符合您的预期:

package main
func main() {
    ch1 := make(chan int)
    done := make(chan struct{})
    go pump(ch1, done) // pump hangs
    <-done // wait for pump
}
func pump(ch chan int, done chan struct{}) {
    ch <- 1
    ch <- 2 // never reached
    close(done) // never reached
}

输出:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    /tmp/sandbox778506014/main.go:7 +0xc0

goroutine 4 [chan send]:
main.pump(0x1043a080, 0x1043a0c0)
    /tmp/sandbox778506014/main.go:10 +0x40
created by main.main
    /tmp/sandbox778506014/main.go:6 +0xa0

游乐场:https://play.golang.org/p/FTFPOBCm4G_0

【讨论】:

  • 如果我不放弃给他时间.sleep,它就不会死锁
  • 为什么写一个损坏没有错?阻塞主进程会死锁
  • 在您的第一个问题上,它会阻塞,但您只是看不到它。 main 正在休眠,pump 被阻塞,等待有人从 chan 接收值,然后 main 突然唤醒并退出。在 Everton 的示例中(这是演示问题的正确方法),main 将在 pump 完成(并关闭 chan)之前退出,但 pump 正在等待有人读取值。因此运行时会理解死锁并通知您。
猜你喜欢
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-14
  • 2017-08-12
  • 1970-01-01
  • 2021-10-12
相关资源
最近更新 更多