У меня есть несколько процедур, которые select
по двум каналам: один канал предоставляет данные, один канал для сигналов (вид «Готово / выход из канала»).
Я использую канал сигналов, чтобы захватывать сигналы (убивать) и грациозно закрывать программы.
Я запускаю "рабочие" подпрограммы из package a
, в то время как функция подпрограммы, которая захватывает сигналы, запускается из package b
.
Я использую пакет сигналов от 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
}
}
}
Программа для перехвата сигналов и вызова 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()
}
}
}
а это мой главный функционал
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.")
}
Когда я прекращаю запущенный процесс, я вижу напечатанное сообщение от Quit
. Я ожидал, что как только канал закроется, в какой-то момент goroutines будет select
случай QuitChan
и вернется.
Но они продолжают бежать; они продолжают обрабатывать предметы с WorkChan
. кажется, что это игнорируется. Что мне здесь не хватает?
Разве канал не закрывается? Почему это все еще открыто?