I have got multiple goroutines that select from two channels: one chan provides data, one chan for signals (kind of done/quit channel).
I use the signals channel to capture signals (kill) and gracefully close the goroutines.
I'm running the 'worker' goroutines from package a, while the goroutine func that captures signals runs from package b.
I use the signals package from https://gist.github.com/reiki4040/be3705f307d3cd136e85.
package a
import "sync"
WorkChan := make(chan int)
QuitChan := make(chan struct{})
func Stop() {
fmt.Println("Stop called, closing channel")
close(QuitChan)
}
func Work(wg *sync.WaitGroup) {
var item int
for {
select {
case item = <- WorkChan:
... processing
case <- QuitChan:
wg.Done()
return
}
}
}
The goroutine to catch signals, and call a.Stop()
package b
import (
"os/signal"
"os"
"syscal"
"a"
)
func Signal() {
sChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-sChan
switch s {
case os.Interrupt, syscall.SIGTERM:
a.Stop()
}
}
}
and this is my main func
package main
import (
"a"
"b"
"sync"
)
func main() {
var wg sync.WaitGroup
go b.Signal()
wg.Add(1) // for simplicity; actual code start multiple goroutines of Work
go a.Work(&wg)
// wait until work is done
wg.Wait()
fmt.Println("Done.")
}
When I kill the running process, I see the printed message from Quit. I expected that once the channel is closed, the goroutines will select the QuitChan case at some point and return.
But they keep running; they continue to process items from WorkChan. seems like it is ignored. What am I missing here?
Doesn't the channel get closed? How come it is still open?
a.QuitChan, that will terminatea's goroutine (sooner or later), but the goroutine in thebpackage has no termination condition, that will run forever. Also, the app will not terminate just because some "random" goroutine ended, the app terminates when themaingoroutine ends (we don't know what yourmaingoroutine is). - iczab's goroutine, and there is no return nor break statement in it, so it will run forever. A goroutine or its loop will not magically end or return just because an independent goroutine ended. - icza"Stop called, closing channel"printed, that is not guarantee that theQuitChanis closed (as the print is before theclose()call). Put a print statement after theclose()and confirm if you see that printed. - iczago vetshould complain about that, I think. - Peter