why is this a deadlock in golang / waitgroup?

go

Solution

You have two problems :

- there's not enough place for all the goroutines as your channel is too small : when your channel is full, the remaining goroutines must wait for a slot to be freed

- `range ch` is still waiting for elements to come in the channel and there's no goroutine left to write on it.

Solution 1 :

Make the channel big enough and, close it so that `range` stops waiting :

ch := make(chan []int, 5)
...
wg.Wait()
close(ch)

Demonstration

This works but this mostly defeats the purpose of channels here as you don't start printing before all tasks are done.

Solution 2 : This solution, which would allow a real pipelining (that is a smaller channel buffer), would be to do the `Done()` when printing :

func main() {
    ch := make(chan []int, 4)
    var m []int

    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            ch <- m
            return
        }()
    }
    go func() {
        for c := range ch {
            fmt.Printf("c is %v\n", c)
            wg.Done()
        }
    }()
    wg.Wait()
}

Demonstration

Problem

I'm not sure what I'm missing but I get a deadlock error. I'm using a buffered channel that I range over after all go routines complete. The channel has the capacity of 4 and I'm running 4 go routines so I'm expecting it to be "closed" automatically once it reaches the max capacity. ``` package main import "fmt" import "sync" func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() ch <- m return }() } wg.Wait() for c := range ch { fmt.Printf("c is %v", c) } } ```

Original source

Related problems