Need Help Understanding Buffered Channels & deadlocks

Hi All,

In advance, i’d like to thank you for taking the time to look at my code and help me understand things.

The code below is a simple execution of a buffered channel. What i’m assuming is happening here is that since the buffer in the channel has a size of 1, multiple writes to it in a short amount of time result in a buffer overflow. However, with a deadlock error message, i’m not sure if that’s the case. This is why i am confused and would like some help understanding this concept.

Here is the code:

package main

import (
	"fmt"
)

func printer(reqChan chan string, resChan chan string){
	for {
		select {
			case m := <- reqChan:
				fmt.Printf("received job [%s]\n", m)
				resChan <- m
		}
	}
}

func main(){
	jobs := 5
	numWorkers := 1
	queSize := 1

	bufChan := make(chan string, queSize)
	resChan := make(chan string, queSize)

	for i := 0; i < numWorkers; i++ {
		go printer(bufChan, resChan)
	}

	// send jobs
	for i := 0; i < jobs; i++ {
		fmt.Println("sending job", i)
		bufChan <- fmt.Sprintf("buff %d", i)
		fmt.Println("sent job", i)
	}

	// collect responses
	for i := 0; i < jobs; i++ {
		fmt.Println(<- resChan)
	}
}

Here is the output & error:

sending job 0
sent job 0
sending job 1
sent job 1
sending job 2
received job [buff 0]
received job [buff 1]
sent job 2
sending job 3
fatal error: all goroutines are asleep - deadlock!

thank you again!

1 Like

The problem is that the printer receives job 0, writes to the resChan which has capacity 1 and then receives job 1 but can’t write to resChan as the first response hasn’t been consumed yet. On the other hand, the main goroutine was able to wrtie jobs 0 and 1 (which were consumed), but when attempting to send job 3 the printer isn’t able to receive it as its blocked waiting for the main goroutine to consume the response. This will never happen as the main goroutine is still waiting to finish sending jobs and thus you get a deadlock where the printer and main are waiting for each other.

1 Like

@iegomez thank you for this reply. I believe this makes some sense to me. If i’m understanding your response, resChan can’t be written to because the jobs are coming in too fast?

1 Like

No, it’s because the messages aren’t being consumed.

1 Like

@iegomez thank you very much, i see it now. The output to resChan never makes it. In fact, there’s no output of ‘buff…’ makes total sense now. I will need to rework this.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.