INTRODUCTION:
I am just starting to learn the Go language and have reached the lesson about concurrency.
I have invented a small task for myself to try to implement what I have learned about closing goroutines.
PROBLEM:
If we close channel it's case
will always be selected in the select
statement, which is a great way to broadcast cancelation signal to all goroutines.
Below I have 2 goroutines and a quit
channel that never gets received.
Code timeouts on Playground.
If I comment out default
part in the goroutines then quit
signal gets received.
QUESTION:
I really do not understand why is this happening and how to fix it, although I am trying.
Can somebody please explain me what is the problem and offer some advice on how to solve it?
package main
import (
"fmt"
"sync"
"time"
)
func positive_numbers(quit chan struct{}, wg *sync.WaitGroup) {
defer wg.Done()
i := 1
for {
select {
case <-quit:
fmt.Println("[+]Quiting...")
return
default:
fmt.Printf("%v ", i)
i++
}
}
}
func negative_numbers(quit chan struct{}, wg *sync.WaitGroup) {
defer wg.Done()
i := -1
for {
select {
case <-quit:
fmt.Println("[-]Quiting...")
return
default:
fmt.Printf("%v ", i)
i--
}
}
}
func main() {
quit := make(chan struct{})
wg := sync.WaitGroup{} // so we can wait for all goroutines to finish
wg.Add(2)
go positive_numbers(quit, &wg)
go negative_numbers(quit, &wg)
go func(quit chan struct{}) {
defer close(quit)
time.Sleep(1 * time.Second)
}(quit)
wg.Wait()
}