Горутины и каналы: как не выстрелить себе в ногу
Конкурентность в Go выглядит обманчиво простой: поставил go перед вызовом — и функция уже работает в отдельной горутине. Но именно эта простота и подводит новичков.
Утечка горутин
Самая частая проблема — горутина, которая никогда не завершится, потому что читает из канала, куда никто уже не пишет. Такие горутины копятся и съедают память.
func worker(jobs <-chan int) {
for j := range jobs {
process(j)
}
}Пока канал jobs открыт и в него пишут — всё хорошо. Закрыли канал через close(jobs) — цикл range корректно завершится.
Правило большого пальца
- Закрывает канал всегда тот, кто пишет, а не тот, кто читает.
- Читать из закрытого канала можно — вернётся нулевое значение и
ok == false. - Писать в закрытый канал — паника.
Держите эти три правила в голове, и половина проблем с каналами исчезнет сама собой.