Комментарии 4
В старых сложных немодных языках было правило - если ты создаешь ресурс, ты обязан его закрыть либо вернуть наружу чтобы его закрыл другой (это про канал, если что), если у тебя есть разделяемый ресурс к которому нельзя обращаться в некоторых стейтах - прикрой его оберткой.
А что до Go, у вас же в нем есть прекрасная конструкция defer - m.Lock() и тут же defer m.Unlock(), c := make(chan ...) и сразу defer Close(c)
Все давно придумано, надо только использовать.
Во всем правы , я постарался упомянуть об этом в статье.
Но бывают заурядные кейсы с мьютексами. defer m.Unlock() иногда может не использоваться , как например в исходниках go для оптимизация и быстрого разлочивания. Именно в продакшене не встречал , но в личных целях приходилось.
С каналами чуть сложнее , ведь не всегда есть желания закрывать по завершению функции , иногда приходится распаралелить запись в канал и придумывать сценарий , где только одна горутина его закроет.
иногда приходится распаралелить запись в канал и придумывать сценарий , где только одна горутина его закроет.
Вот так вот не надо, не надо сценариев, когда один из писателей закрывает канал. И придумывать такие сценарии тоже не надо, все придумано до нас: sync.WaitGroup - канал должен закрываться тогда и только тогда, когда мы гарантированно не собираемся в него больше писать
1.Наверное КДПВ лучше сменить на что-то нейтральное
2.Как выше уже указали, есть defer, и я дополню, что лучше, чтобы сразу после выделения ресурса стараться размещать defer (ресурс).Close(). «Глазками» проще увидеть и перестать беспокоиться о закрытии ресурса.
r.Open()
defer r.Close()
Часто видел, что, например, в одной ветке исполнения кода закрыли ресурс, а в другой забыли.
r.Open()
if .... {
.....
r.Close()
return
} else if .... {
....
return
} else {
...
}
r.Close()
А где память? Утечка goroutine и как ее пофиксить