Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗goSpSyAt 171 of 280 menu
◀ ▶

Атомарный счетчик в Go

Для простого счетчика можно обойтись без замка: процессор выполняет приращение одной неделимой операцией. Пакет sync/atomic дает типы с методами, которые безопасны при вызове из разных горутин одновременно.

Тип atomic.Int64 хранит число внутри. Метод Add прибавляет заданную величину и возвращает новое значение; Load читает текущее число без гонки. Для целого счетчика этого часто достаточно вместо Mutex.

Сто веток с атомарным приращением:

package main import ( "fmt" "sync" "sync/atomic" ) func main() { var n atomic.Int64 var wg sync.WaitGroup wg.Add(100) for i := 0; i < 100; i++ { go func() { defer wg.Done() n.Add(1) }() } wg.Wait() fmt.Println(n.Load()) }

На экране "100": каждое приращение доходит, хотя отдельного замка в коде нет.

Чтение после накопления:

package main import ( "fmt" "sync/atomic" ) func main() { var total atomic.Int64 total.Add(3) total.Add(2) fmt.Println(total.Load()) }

Дан следующий код:

var hits atomic.Int64 var wg sync.WaitGroup func bump(wg *sync.WaitGroup) { defer wg.Done() hits.Add(1) }

Запустите bump двадцать раз с ожиданием группы и выведите итог через чтение счетчика.

Дан следующий код:

var k int var wg sync.WaitGroup func step(wg *sync.WaitGroup) { defer wg.Done() k++ }

Замените обычное целое на атомарный счетчик и добейтесь точного итога при пятидесяти ветках.

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

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить