Skip to content

Закрытие каналов: решения вежливого закрытия

Многие разработчики предпочитают использовать sync.Once для закрытия каналов.

Пришло время поработать с кодом!

Конечно, мы также можем использовать sync.Mutex, чтобы избежать многократного закрытия канала.

Пришло время поработать с кодом!

Эти способы могут быть вежливыми, но они не могут избежать гонки данных. В настоящее время спецификация Go не гарантирует отсутствие гонок данных, когда канал закрывается, а операции отправки канала выполняются одновременно. Если функция SafeClose вызывается одновременно с операцией отправки канала в тот же канал, может произойти гонка данных,хотя она обычно не приносит никакого вреда.

Решения, которые изящно закрывают каналы

Одним из недостатков вышеупомянутой функции SafeSend является то, что ее вызовы нельзя использовать в качестве операций отправки, которые следуют за case ключевым словом в select блоках. Другим недостатком вышеизложенного функций SafeSend и  SafeClose является то, что многие люди, включая меня, сочли бы приведенные выше решения с использованием panic/ recover и sync пакета некрасивыми. Далее будут представлены некоторые чисто канальные решения без использования panic/ recover и sync пакета для всех видов ситуаций.

Давай рассмотрим несколько примеров, в которых sync.WaitGroup используется для полноты этих примеров. Его использование на практике может быть не всегда необходимым.