Two consecutive reads from a buffered channel results in deadlock

65 views
Skip to first unread message

Michael Dwyer

unread,
Sep 4, 2021, 8:55:15 PM9/4/21
to golang-nuts
I encountered a deadlock when reading from a buffered channel.
The deadlock occurs when an attempt is made to read from the channel twice, without an intermediate write to the channel.

The problematic code is as follows:

func main() {
myInt      := 432

readerChan := make(chan int, 3)

for forI := 0; forI <= 10000; forI++ {
readerChan <- myInt
fmt.Printf("%d:", <- readerChan)
fmt.Printf("%d:", <- readerChan)
}

close(readerChan)
}

The first read from variable readerChan succeeds.
The second read from variable readerChan results in a deadlock.

I have two links to playground.
The first link is the problematic code.
The second link is for similar code that has an intervening write to the channel.

I understand that a buffered channel allows a queue of results to be stored from other Go routines writing to the channel.
But, the code is attempting multiple read operations.

Looking for a technical explanation to help me better understand this particular case.
Thanks in advance ...


The problematic playground link : https://play.golang.org/p/veo7phAZzMv
The working playground link     : https://play.golang.org/p/qvYZNN9keqN


THANX(MKD).

Kurtis Rader

unread,
Sep 4, 2021, 9:31:32 PM9/4/21
to Michael Dwyer, golang-nuts
On Sat, Sep 4, 2021 at 5:55 PM Michael Dwyer <michael...@gmail.com> wrote:
I encountered a deadlock when reading from a buffered channel.
The deadlock occurs when an attempt is made to read from the channel twice, without an intermediate write to the channel.

That is not a deadlock. Reading from a buffered channel blocks when the channel is empty. From https://golang.org/ref/spec#Channel_types:
 

Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A nil channel is never ready for communication.

You can use the "select" operator (https://golang.org/ref/spec#Select_statements) to detect if the channel is empty.
 
The problematic code is as follows:

func main() {
myInt      := 432

readerChan := make(chan int, 3)

for forI := 0; forI <= 10000; forI++ {
readerChan <- myInt
fmt.Printf("%d:", <- readerChan)
fmt.Printf("%d:", <- readerChan)
}

close(readerChan)
}

The first read from variable readerChan succeeds.
The second read from variable readerChan results in a deadlock.

I have two links to playground.
The first link is the problematic code.
The second link is for similar code that has an intervening write to the channel.

I understand that a buffered channel allows a queue of results to be stored from other Go routines writing to the channel.
But, the code is attempting multiple read operations.

Looking for a technical explanation to help me better understand this particular case.
Thanks in advance ...


The problematic playground link : https://play.golang.org/p/veo7phAZzMv
The working playground link     : https://play.golang.org/p/qvYZNN9keqN


THANX(MKD).

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/44057a7a-b0aa-4ea1-9fb3-39836cd5713dn%40googlegroups.com.


--
Kurtis Rader
Caretaker of the exceptional canines Junior and Hank

Dan Kortschak

unread,
Sep 4, 2021, 9:32:28 PM9/4/21
to golan...@googlegroups.com
What would you expect to happen here? A chan that has had one item sent
and then one item received has no items on it, so a receive must wait
until another item is sent.

Michael Dwyer

unread,
Sep 4, 2021, 10:00:07 PM9/4/21
to golang-nuts
Kurtis, thank you for your explanation and for the links, providing more detailed information on the subject matter.
This was what I was looking for, a reasoned explanation and documentation that would explain why this condition occurred.

Always good when there are those willing to provide helpful hints and documentation, so others can learn.

Greatly appreciate your time an assistance.


THANX(MKD).
Reply all
Reply to author
Forward
0 new messages