Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Golang: goroutine, context, cancel, error group, graceful shutdown

Как в Go корректно завершить несколько горутин при возникновении ошибки в одной из них? (*)

Вопрос проверяет понимание паттернов конкурентности в Go, в частности graceful shutdown нескольких горутин при ошибке.

Короткий ответ

Используйте контекст с отменой (context.WithCancel) или errgroup из пакета golang.org/x/sync. При ошибке в одной горутине вызывайте cancel(), остальные горутины должны проверять ctx.Done() и завершаться. Errgroup автоматически отменяет контекст при первой ошибке.

Длинный ответ

Проблема завершения горутин при ошибке

В Go горутины не имеют встроенного механизма уведомления друг друга об ошибках. Если одна горутина завершилась с ошибкой, остальные продолжают работу, что может привести к утечкам ресурсов или некорректному поведению. Для решения этой задачи применяются контексты с отменой и пакет errgroup.

Использование context.WithCancel

Создайте контекст с функцией отмены и передавайте его во все горутины. При возникновении ошибки вызовите cancel(), а горутины должны проверять ctx.Done() в цикле или select.

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

go func() {
    select {
    case <-ctx.Done():
        return
    case result <-ch:
        // обработка
    }
}()

// при ошибке:
cancel()

Пакет errgroup

Errgroup из golang.org/x/sync/errgroup предоставляет удобную обёртку. Он автоматически отменяет контекст при первой ошибке и ожидает завершения всех горутин.

g, ctx := errgroup.WithContext(context.Background())

for i := 0; i < 3; i++ {
    i := i
    g.Go(func() error {
        if i == 1 {
            return errors.New("ошибка")
        }
        select {
        case <-ctx.Done():
            return ctx.Err()
        default:
            time.Sleep(time.Second)
        }
        return nil
    })
}

if err := g.Wait(); err != nil {
    log.Println("ошибка:", err)
}

Вывод

Используйте errgroup для группового управления горутинами с автоматической отменой при ошибке. Для более тонкого контроля применяйте context.WithCancel вручную. Это стандартный паттерн для надёжной обработки ошибок в конкурентном коде Go.

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    6

Навыки

  • Golang

    Golang

Ключевые слова

#goroutine

#context

#cancel

#error group

#graceful shutdown

Подпишись на Golang Developer в телеграм

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.