This question already has an answer here:
I'm trying to experiment with go routines about who gets the message first. However, when the main goroutine terminates, some go routines are still hanging around. I see this through the stack trace from panic
. However, If I add time.Sleep
they all terminate. I guess this is because, when the main go routines ends, Go runtime couldn't find time to terminate the others.
package main
import (
"fmt"
"time"
)
func main() {
for i := 0; i < 1000000; i++ {
algo()
}
// without this, some goroutines do not terminate
// time.Sleep(time.Second)
panic("")
}
func algo() {
c := make(chan int)
wait := make(chan bool)
go racer(1, wait, c)
go racer(2, wait, c)
go racer(3, wait, c)
go racer(4, wait, c)
go racer(5, wait, c)
// who gets it first
c <- 5
close(wait)
}
func racer(name int, wait chan bool, c chan int) {
select {
case <-wait:
case v := <-c:
fmt.Println(name, ":", v)
}
}
</div>
That's exactly what sync.WaitGroup
is for. Here's a toy example taken from this blog post:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
messages := make(chan int)
var wg sync.WaitGroup
// you can also add these one at
// a time if you need to
wg.Add(3)
go func() {
defer wg.Done()
time.Sleep(time.Second * 3)
messages <- 1
}()
go func() {
defer wg.Done()
time.Sleep(time.Second * 2)
messages <- 2
}()
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
messages <- 3
}()
go func() {
for i := range messages {
fmt.Println(i)
}
}()
wg.Wait()
}