Вопрос проверяет знание механизмов синхронизации горутин в Go, что важно для написания корректных конкурентных программ.
В Go конкурентность строится на горутинах, которые выполняются параллельно. Для координации их работы и предотвращения гонок данных используются несколько механизмов. Каждый из них решает свою задачу: передача данных, защита критических секций, ожидание завершения или управление жизненным циклом.
Каналы — это основной способ обмена данными между горутинами. Они обеспечивают синхронизацию: отправка и получение блокируют горутину до готовности другой стороны. Каналы бывают буферизированными и небуферизированными. Небуферизированный канал синхронизирует выполнение, а буферизированный позволяет отправлять несколько значений без блокировки.
ch := make(chan int)
go func() { ch <- 42 }()
value := <-ch // получаем 42, горутина завершиласьМьютекс защищает общие данные от одновременного доступа. Он блокирует критическую секцию, чтобы только одна горутина могла выполнять код в данный момент. Это необходимо, когда несколько горутин изменяют одну переменную.
var mu sync.Mutex
var counter int
func increment() {
mu.Lock()
counter++
mu.Unlock()
}WaitGroup позволяет главной горутине ожидать завершения набора горутин. Это удобно, когда нужно дождаться окончания всех параллельных задач перед продолжением работы.
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// работа
}()
}
wg.Wait()Пакет sync/atomic предоставляет функции для атомарного чтения и записи чисел. Они быстрее мьютексов для простых счетчиков и флагов, так как не блокируют горутину.
var counter int64
atomic.AddInt64(&counter, 1)Контексты используются для отмены горутин и передачи значений через границы API. Они позволяют остановить выполнение при таймауте или отмене пользователем.
ctx, cancel := context.WithCancel(context.Background())
go func() {
select {
case <-ctx.Done():
return
default:
// работа
}
}()
cancel() // отменяемВыбор механизма зависит от задачи: для передачи данных используйте каналы, для защиты общих ресурсов — мьютексы, для ожидания группы горутин — WaitGroup, для простых счетчиков — атомарные операции, для управления отменой — контексты. Правильное применение этих инструментов обеспечивает безопасную и эффективную конкурентность в Go.
Уровень
Рейтинг:
5
Сложность:
4
Навыки
JavaScript
Node.js
Ключевые слова
Подпишись на Golang Developer в телеграм