# #go #goroutine
Вопрос:
Шаблон Does для выбора выхода гарантирует, что все функции будут возвращены до завершения цикла.
Рассмотрим следующий код
func FnBusy() {
log.Println("Entering FnBusy")
time.Sleep(1 * time.Minute)
log.Println("Exiting FnBusy")
}
func TestGoRoutineStop(t *testing.T) {
quit := make(chan interface{})
wg := sync.WaitGroup{}
ticker := time.NewTicker(10 * time.Millisecond)
defer ticker.Stop()
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
case <-quit:
log.Println("Quit Called")
return
case <-ticker.C:
FnBusy()
}
}
}()
time.Sleep(150 * time.Millisecond)
close(quit)
wg.Wait()
}
Когда я запускаю этот тест, я получаю следующий вывод
=== RUN TestGoRoutineStop
2021/09/20 11:03:18 Entering FnBusy
2021/09/20 11:04:18 Exiting FnBusy
2021/09/20 11:04:18 Entering FnBusy
2021/09/20 11:05:18 Exiting FnBusy
2021/09/20 11:05:18 Entering FnBusy
2021/09/20 11:06:18 Exiting FnBusy
2021/09/20 11:06:18 Quit Called
--- PASS: TestGoRoutineStop (180.01s)
Что я хочу понять, так это когда close(quit)
вызывается, и если FnBusy
он все еще выполняется, будет ли он ждать завершения
Комментарии:
1. Гороутины выполняют код последовательно.
case <- quit
Путь к коду не будет выполняться во времяFnBusy
выполнения.2. К вашему сведению — вставленный вами код не может выдать вставленный вами вывод, так как
FnBusy
он ожидает одну минуту, а подпрограмма в main ожидает 150 мс, цикл завершится после одного запускаFnBusy
3. @Inian Вполне вероятно, что тикер и канал выхода будут готовы во второй раз при выполнении инструкции select. Если выбор принимает регистр тикера, то
FnBusy
он будет выполнен дважды.