Я знаю, что если есть более одного сообщения, которое может выполняться в заявлении select
, то одно из них выбирается случайным образом. Я пытаюсь найти альтернативный подход, который может предпочесть одно общение другому.
Фон состоит в том, что я отправляю значения в рутине по каналу, который уничтожается с помощью контекста. Когда я убиваю его, я хочу, чтобы канал был немедленно закрыт, но в настоящее время код иногда отправляет окончательное значение на канал перед его закрытием.
Вот упрощенная версия кода:
ctx, cancel := context.WithCancel(context.Background())
ch := make(chan int)
go func() {
defer close(ch)
for i := 1; ; i++ {
select {
case <-ctx.Done():
return
case ch <- i:
}
}
}()
print(<-ch)
print(<-ch)
cancel()
print(<-ch)
print(<-ch)
Иногда выводится 1200, но обычно 1230. Попробуйте это на игровой площадке
Есть ли идеи, как реорганизовать код в пользу первого случая? (Т.е. он всегда должен печатать 1200.)
Timer.Reset()
- person Burak Serdar   schedule 01.08.2020chan
после вызоваcancel()
, иначе горутина, записывающая в него, может заблокироваться и никогда не завершиться. Кстати, я бы предпочел не читать чан после отмены, и в этом весь смысл этого вопроса. - person AJR   schedule 03.08.2020the goroutine will not block ...
Спасибо @Peter, вы правы. Больше всего меня беспокоила утечка горутины, но теперь я вижу, что это невозможно, поэтому я думаю, что решением является никаких изменений в моем исходном коде. - person AJR   schedule 24.08.2020