【问题标题】:golang all goroutines are asleep - deadlockgolang所有goroutines都睡着了 - 死锁
【发布时间】:2020-07-16 07:45:33
【问题描述】:

运行 follow golang sn-p 时出现错误。 我认为进度将在 wg.Wait() 处阻塞,直到 go 例程结束。那么该值将从 c1 获得。但它可能不会按预期进行。

func main() {

c1 := make(chan string)
//var c1 chan string
var wg sync.WaitGroup

wg.Add(1)
go func() {
    defer wg.Done()
    fmt.Printf("go routine begin\n")
    time.Sleep(1 * time.Second)
    c1 <- "one"
    fmt.Printf("go routine done\n")
}()
wg.Wait()
fmt.Printf("done c1: %v\n", <-c1)
fmt.Printf("out\n")
}

错误信息是,

 go routine begin
 fatal error: all goroutines are asleep - deadlock!

【问题讨论】:

    标签: go deadlock channel


    【解决方案1】:

    c1 的写入永远不会执行,因为对c1 的读取是在wg.Wait() 之后进行的,直到写入c1 才会停止。所以主 goroutine 在 wg.Wait() 等待,嵌套 goroutine 在 c1 write 等待。

    您可以使通道缓冲,或等待c1 在单独的 goroutine 上读取。

    【讨论】:

      【解决方案2】:

      在 Golang 中,无缓冲通道上的写入操作是阻塞的。从文档中可以清楚地看到。

      您的执行被阻止在

      c1 <- "one"
      

      延迟声明

      defer wg.Done()
      

      从不执行。

      【讨论】:

        【解决方案3】:

        在您的代码中,您正在使用一个无缓冲通道,该通道会阻塞直到接收器接收到“一个”。在这种情况下,代码不会超过 wg.Wait(),因为 wg.Done() 永远不会被执行。

        我想这就是你所追求的。

        func main() {
        
        c1 := make(chan string)
        //var c1 chan string
        
        go func() {
            fmt.Printf("go routine begin\n")
            time.Sleep(1 * time.Second)
            c1 <- "one"
            fmt.Printf("go routine done\n")
        }()
        fmt.Printf("done c1: %v\n", <-c1)
        fmt.Printf("out\n")
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-06
          • 2012-01-06
          • 2023-02-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-28
          相关资源
          最近更新 更多