4

go 语言的一个死锁问题

 2 years ago
source link: https://www.v2ex.com/t/781192
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  Go

go 语言的一个死锁问题

  v2defy · 1 天前 · 934 次点击

两个 goroutine,一个输出奇数,一个输出偶数,交替输出,最终达到顺序输出的目的。

其中 B 协程运行到最后的时候,如果不做特殊的处理,继续向 A 通道写入数据,会导致 A 通道死锁。

感到很奇怪,为什么会这样? A 通道这时候是没有数据的,为什么不让写?

package main

import (
  "fmt"
)

func main() {
  // 创建 3 个 channel,A,B 和 Exit
  A := make(chan bool)
  B := make(chan bool)
  Exit := make(chan bool)

  go func() {
    // 如果 A 通道是 true,我就执行
    for i := 1; i <= 10; i += 2 {
      if ok := <-A; ok {
        fmt.Println("A 输出", i)
        B <- true
      }
    }
  }()

  go func() {
    defer func() { Exit <- true }() // 这个协程的活干完之后,向主 goroutine 发送信号
    // 如果 B 通道是 true,我就执行
    for i := 2; i <= 10; i += 2 {
      if ok := <-B; ok {
        fmt.Println("B 输出", i)
        if i != 10 { // 如果 i 等于 10 了,就不要再向 A 通道写数据了,否则将导致 A 通道死锁,至于为什么,坦白说我很疑惑
          A <- true
        }
      }
    }
  }()

  A <- true // 启动条件
  <-Exit    // 结束条件
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK