Sobes.tech
Назад к вопросам
Middle+
1

Задача 4: Найти ошибки в коде с каналами и горутинами (двойное закрытие канала)

Компании, где спрашивали
СБЕРСБЕР

Ответ от нейросети

sobes.tech AI

Ошибка двойного закрытия канала в Go возникает, когда один и тот же канал закрывается более одного раза, что приводит к панике.

Типичный пример ошибки:

dataCh := make(chan int)

// Горутина, которая закрывает канал
go func() {
    for i := 0; i < 5; i++ {
        dataCh <- i
    }
    close(dataCh) // Закрываем канал
}()

// В другом месте тоже пытаемся закрыть канал
close(dataCh) // ПАНИКА: закрытие уже закрытого канала

Как избежать:

  • Закрывать канал должен только тот, кто его пишет (отправляет данные).
  • Получатели не должны закрывать канал.
  • Если несколько горутин пишут в канал, нужно синхронизировать закрытие (например, через sync.WaitGroup).

Пример правильного использования:

func producer(ch chan<- int) {
    for i := 0; i < 5; i++ {
        ch <- i
    }
    close(ch) // Закрываем канал только здесь
}

func consumer(ch <-chan int) {
    for val := range ch {
        fmt.Println(val)
    }
}

func main() {
    ch := make(chan int)
    go producer(ch)
    consumer(ch)
}

Таким образом, чтобы избежать двойного закрытия, нужно строго определить ответственность за закрытие канала и использовать синхронизацию при необходимости.