Curious
Curious

Reputation: 21510

How to get the number of elements in an unbuffered channel

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 "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)
}

Upvotes: 2

Views: 734

Answers (1)

Grzegorz Żur
Grzegorz Żur

Reputation: 49181

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.

Upvotes: 3

Related Questions