如何获取无缓冲通道中的元素数量

时间:2017-01-25 19:34:15

标签: go deadlock channel goroutine

我的情况是我的程序死锁,我想调试它并告诉无缓冲通道中有多少元素,有没有办法在Go中执行此操作?以下代码不会像我期望的那样输出2(进一步的死锁,这也是我找不到的原因)

package main

import "fmt"

func main() {
    channel := make(chan string)
    done_channel := make(chan bool)
    go func() {
        channel <- "value"
        channel <- "value"
        fmt.Println(len(channel))
        done_channel <- true
    }()
    variable := <- channel
    fmt.Println(variable)
    ok := <- done_channel
    fmt.Println(ok)
}

1 个答案:

答案 0 :(得分:3)

Go运行时有一个刚刚遇到的死锁检测器。探测器为您提供解决问题所需的所有信息。您不需要分析频道长度。

让我们看一下你的程序输出

value
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    /home/grzesiek/test.go:16 +0x17e

goroutine 5 [chan send]:
main.main.func1(0xc42001a0c0, 0xc42001a120)
    /home/grzesiek/test.go:10 +0x99
created by main.main
    /home/grzesiek/test.go:13 +0x9c
exit status 2

据说所有goroutine都睡着了(被封锁),无法取得进展。阻塞的goroutine与阻塞操作和导致阻塞的行一起列出。

Goroutine 1(主要)正试图从第16行的频道done_channel中读取。

Goroutine 5(由函数调用运算符()在第13行创建)正在尝试写入第10行中的通道channel。它将永远不会进一步,因为另一方没有goroutine香奈儿因此,它永远不会写入done_channel

该程序被阻止,因为没有goroutine可以进一步,主goroutine也被阻止。

请注意,当主goroutine结束时,Go程序结束,因此如果您不尝试从done_channel读取,则不会发生此死锁。