Home > Blockchain >  Synchronizing with a GO waitgroup
Synchronizing with a GO waitgroup

Time:02-11

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

CodePudding user response:

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.

CodePudding user response:

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.

  • Related