【问题标题】:Why does this result in deadlock?为什么这会导致死锁?
【发布时间】:2019-12-27 23:29:42
【问题描述】:

我不明白为什么下面的代码会导致死锁...谁能帮帮我?

在什么情况下,通道会陷入僵局?我真的很困惑……

下面的代码是按这个顺序打印字母和数字 “12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728” 我想使用通道来实现这个目标,但陷入僵局。 删除 numberDone 频道时,一切正常。

import (
    "fmt"
)

func main() {
    AlterPrint()
}

// POINT: communicate between goroutines by channel

func AlterPrint(){
  letter, number := make(chan bool), make(chan bool)
  letterDone := make(chan bool)
  numberDone := make(chan bool)
  go func() {
    i := 1
    for {
      if i > 28 {
          numberDone <- true
          return
      }
      select{
        case <-number: {
          fmt.Print(i)
          i++
          fmt.Print(i)
          i++
          letter <- true
          break
        }
        default: {
          break
        }
      }

    }
  }()

  go func(){
    i := 'A'
    for {
      if i > 'Z' {
        letterDone <- true
        return
      }
      select{
        case <-letter: {
          fmt.Print(string(i))
          i++
          fmt.Print(string(i))
          i++
          number <- true
          break
        }
        default: {
          break
        }
      }
    }
  }()
  number <- true
  <- letterDone
  <- numberDone
}```

I expect the output of "12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728", 
but the actual output is 
goroutine 1 [chan receive]:
main.AlterPrint()
    /tmp/54841538.go:66 +0x183
main.main()
    /tmp/54841538.go:7 +0x14

goroutine 5 [chan send]:
main.AlterPrint.func1(0xc82000c240, 0xc82000c180, 0xc82000c120)
    /tmp/54841538.go:31 +0x25a
created by main.AlterPrint
    /tmp/54841538.go:40 +0xde
exit status 2

【问题讨论】:

  • 对不起,我错过了一些错误信息。实际输出为: 12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728 致命错误:所有goroutines are sleep - deadlock! goroutine 1 [chan 接收]: main.AlterPrint() /home/runner/alter_print.go:62 +0x157 main.main() /home/runner/main.go:4 +0x20 goroutine 18 [chan send]: main. AlterPrint.func1(0xc000074180, 0xc0000740c0, 0xc000074060) /home/runner/alter_print.go:27 +0x148 由 main.AlterPrint 创建 /home/runner/alter_print.go:14 +0xd9 退出状态 2

标签: go channel


【解决方案1】:

它实际上应该打印您所期望的,然后出现死锁。第二个 goroutine 完成一切,发送 letterdone 并终止。此时,main 开始等待 numberdone。第一个 goroutine 打印最后两个数字,并在 letter

【讨论】:

  • 我认为这不是真的。两个 goroutine 尝试做的第一件事是在无缓冲通道上发送,这是一个阻塞操作,将停止两个 goroutine。在生成 goroutines 之后,main 还尝试在没有任何内容读取的无缓冲通道上发送,因此不可能发生任何操作。
  • 第一个 goroutine 将尝试从
  • 对不起,我错过了一些错误信息。实际输出为: 12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728 致命错误:所有goroutines are sleep - deadlock! goroutine 1 [chan 接收]: main.AlterPrint() /home/runner/alter_print.go:62 +0x157 main.main() /home/runner/main.go:4 +0x20 goroutine 18 [chan send]: main. AlterPrint.func1(0xc000074180, 0xc0000740c0, 0xc000074060) /home/runner/alter_print.go:27 +0x148 由 main.AlterPrint 创建 /home/runner/alter_print.go:14 +0xd9 退出状态 2
  • 这证实了我的分析。仅当 i
猜你喜欢
  • 2012-08-27
  • 2015-03-09
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
相关资源
最近更新 更多