1

Why is this a deadlock in example 1, and does not deadlock nor print anything in example 2 ?

Example 1.)

func main() {

    w := sync.WaitGroup{}
    w.Add(4)
    c := make(chan int)

    go func() { c <- 1; w.Done() }()
    go func() { c <- 2; w.Done() }()
    go func() { c <- 3; w.Done() }()

    go func() { println(len(c)); w.Done() }()

    w.Wait()
}

Example 2.)

func main() {
    w := sync.WaitGroup{}
    w.Add(3)
    c := make(chan int)

    go func() { c <- 1; w.Done() }()
    go func() { c <- 2; w.Done() }()
    go func() { c <- 3; w.Done() }()

    go func() { w.Wait(); println(len(c)) }()
}
icza
  • 389,944
  • 63
  • 907
  • 827
user39950
  • 464
  • 3
  • 15

2 Answers2

1

In the first example, the channels won't be able to send since there is no receiver on the other end of the unbuffered channel. The sent will block forever. And therefore the waitgroup will wait forever. This is a deadlock situation as your program is not able to continue at all.

In the second case, the same thing happens, but you wait in a separate goroutine. So the main function is able to continue. It's not a complete deadlock. In this case, the continuation means the program just exists.

The Fool
  • 16,715
  • 5
  • 52
  • 86
  • Ok so channels must have a receiver - did not know that! – user39950 Feb 08 '22 at 12:56
  • 1
    They must have a receiver, if they are unbuffered. This is an important sync mechanism. If you do not want them to block until it has been received, you need to use a buffered channel. – The Fool Feb 08 '22 at 12:58
0

Your first example launches 3 goroutines, and each tries to send a value on the c unbuffered channel. Since no one receives from the channel, all these will block. So the main() waiting for them to complete, will also be blocked. All goroutines are blocked: deadlock.

In your second example the main() function "just" launches goroutines and does not do anything after that. And when the main goroutine finishes (when your main() function returns), your app ends as well, it does not wait for other non-main goroutines to finishes. For details, see No output from goroutine.

icza
  • 389,944
  • 63
  • 907
  • 827