0Pricing
Go Academy · Урок

Шаблон семафора

Ограничение конкурентности с помощью канала-семафора

«Шаблон семафора» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Что такое семафор

Семафор ограничивает количество горутин, одновременно выполняющих операцию. Он предотвращает исчерпание ресурсов (например, из-за слишком большого числа открытых подключений к базе данных или исходящих HTTP-запросов).

Буферизованный канал как семафор

Буферизованный канал вместимостью N действует как счётный семафор. Получение разрешения выполняется отправкой в канал (при заполненном канале операция блокируется), а освобождение — получением из него.

sem := make(chan struct{}, 10)

func withSem(f func()) {
    sem <- struct{}{} // acquire
    defer func() { <-sem }() // release
    f()
}

Горутина для каждой задачи с семафором

Запускайте по одной горутине на каждую задачу, но ограничивайте параллелизм с помощью семафора:

sem := make(chan struct{}, 5)
for _, job := range jobs {
    sem <- struct{}{}
    go func(j Job) {
        defer func() { <-sem }()
        process(j)
    }(job)
}

Опустошение семафора в конце

После запуска всех горутин опустошите семафор, чтобы убедиться, что все они завершились до возврата:

// After the loop, acquire all N slots (blocks until all goroutines release)
for i := 0; i < cap(sem); i++ {
    sem <- struct{}{}
}

golang.org/x/sync/semaphore

Для взвешенного семафора (например, если горутины используют разный объём ресурсов) используйте тип semaphore.Weighted:

s := semaphore.NewWeighted(100)
// acquire 10 units
if err := s.Acquire(ctx, 10); err != nil { return err }
defer s.Release(10)
// do work

Получение с учётом контекста

Метод Acquire взвешенного семафора учитывает контекст и возвращает ошибку, если контекст отменён до того, как семафор стал доступен.

TryAcquire

s.TryAcquire(n) получает n единиц, только если они доступны немедленно, и в противном случае возвращает false. Полезно для непараллельных проверок.

Семафор и пул работников

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

Ограничение параллелизма HTTP

Оберните HTTP-обработчик или клиент в семафор, чтобы предотвратить слишком большое количество одновременно выполняющихся исходящих запросов или горутин входящих обработчиков.

Ограничение подключений к базе данных

Вместо семафора задайте db.SetMaxOpenConns(n) и db.SetMaxIdleConns(m) — пакет sql самостоятельно управляет параллелизмом пула подключений.

Справедливость семафора

Семафоры на основе буферизованных каналов примерно справедливы (FIFO для горутин, заблокированных при отправке), но строгая гарантия отсутствует. Пакет взвешенных семафоров предоставляет более строгие гарантии справедливости.

Быстрая проверка

Как буферизованный канал реализует семафор?

Повторение: шаблон семафора

Ключевые моменты:

  • Буферизованный канал sem := make(chan struct{}, N) для простых семафоров
  • Для захвата отправьте значение, для освобождения получите его; освобождение всегда следует выполнять через defer
  • golang.org/x/sync/semaphore для взвешенного варианта с поддержкой контекста
  • Используйте errgroup.SetLimit для простого ограничения параллелизма в группе

Часто задаваемые вопросы

Урок «Шаблон семафора» бесплатный?

Да — полный текст урока «Шаблон семафора» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Шаблон семафора»?

Ограничение конкурентности с помощью канала-семафора Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Шаблон семафора»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Шаблоны конвейеров и этапов
  2. errgroup для конкурентной обработки ошибок
  3. Шаблон семафора
  4. Обнаружение утечек и отмена
← Назад к Go Academy