Why is WaitGroup.Wait() hanging when using it with go test?


Here’s a simple example of what I mean

package main

import (

func TestWaitGroup(t *testing.T) {
    var wg sync.WaitGroup
    quitSig := make(chan struct{})
    go func(wg sync.WaitGroup, quitChan, chan struct{}) {
        defer func() {
        t.Log("waiting for quit channel signal...")
        t.Log("signal received")
    }(wg, quitSig)
    t.Log("Done sleeping")
    t.Log("closed quit signal channel")
    t.Log("goroutine shutdown")

When I run this, I get the following

=== RUN   TestWaitGroup
    main.go:18: waiting for quit channel signal...
    main.go:23: Done sleeping
    main.go:25: closed quit signal channel
    main.go:20: signal received
    main.go:14: Done...
    main.go:16: Done!

Where it just hangs until it timesout. If you just do defer wg.Done() the same behaviour is observed. I’m running go1.18. Is this a bug or am I using not using WaitGroups properly in this context?


Two issues:

  • don’t copy sync.WaitGroup: from the docs:

    • A WaitGroup must not be copied after first use.
  • you need a wg.Add(1) before launching your work – to pair with the wg.Done()

wg.Add(1) // <- add this

go func (wg *sync.WaitGroup ...) { // <- pointer
}(&wg, quitSig) // <- pointer to avoid WaitGroup copy


Answered By – colm.anseo

Answer Checked By – Mary Flores (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.