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

huangapple go评论76阅读模式
英文:

How to get the number of elements in an unbuffered channel

问题

我现在是你的中文翻译助手,以下是你提供的代码的翻译:

我遇到了一个程序死锁的情况,我想要调试并告诉有多少个元素在一个无缓冲通道中,有没有办法在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)
}

希望对你有帮助!

英文:

I am in a situation where my program is deadlocking and I want to debug this and tell how many elements are in an unbuffered channel, is there any way to do this in Go? The following code does not output a 2 as I would expect (further it deadlocks, which is also something I cannot find a reason for)

package main

import &quot;fmt&quot;

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

答案1

得分: 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(主goroutine)正在尝试从第16行的done_channel通道中读取数据。

Goroutine 5(由函数调用运算符()在第13行创建)正在尝试向第10行的channel通道写入数据。它将无法继续执行,因为通道的另一侧没有goroutine。因此,它将永远不会向done_channel写入数据。

程序被阻塞,因为没有goroutine可以继续执行,而主goroutine也被阻塞。

请注意,当主goroutine结束时,Go程序也会结束,因此如果你不尝试从done_channel读取数据,就不会发生这种死锁情况。

英文:

Go runtime has a deadlock detector that you just came across. The detector is giving you all information you need to solve the problem. You don't need to analyze the channel length.

Let's look at the output of your program

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

It is saying that all goroutines are asleep (blocked) and no progress is possible. The blocked goroutines are listed altogether with the blocking operation and line that caused the blockage.

Goroutine 1 (main) is trying to read from channel done_channel in line 16.

Goroutine 5 (created in line 13 by the function call operator ()) is trying to write to channel channel in line 10. It will never go further as there is no goroutine on the other side of the chanel. Therefore it will never write to done_channel.

The program is blocked because no goroutine can go further and main goroutine is also blocked.

Please be aware that the Go program ends when main goroutine ends, so this dead lock would not occur if you would not try to read from done_channel.

huangapple
  • 本文由 发表于 2017年1月26日 03:34:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/41860130.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定