gobyexample/examples/atomic-counters/atomic-counters.go
2019-10-08 16:42:41 +03:00

51 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Основным механизмом управления состоянием в Go является
// связь по каналам. Мы видели это, например, с [пулами воркеров](worker-pools).
// Есть несколько других вариантов управления состоянием.
// Здесь мы рассмотрим использование пакета `sync/atomic`
// для _атомарных счетчиков_, к которым обращаются горутины.
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
// Мы будем использовать целое число без знака
// для представления нашего (всегда положительного)
// счетчика.
var ops uint64
// WaitGroup поможет нам подождать, пока все горутины
// завершат свою работу.
var wg sync.WaitGroup
// Мы запустим 50 горутин, каждая из которых увеличивает
// счетчик ровно в 1000 раз.
for i := 0; i < 50; i++ {
wg.Add(1)
go func() {
for c := 0; c < 1000; c++ {
// Для атомарного увеличения счетчика мы
// используем AddUint64, присваивая ему адрес
// памяти нашего счетчика `ops` с префиксом `&`.
atomic.AddUint64(&ops, 1)
}
wg.Done()
}()
}
// Ждем пока завершатся горутины.
wg.Wait()
// Теперь доступ к `ops` безопасен, потому что мы знаем,
// что никакие другие горутины не пишут в него. Безопасное
// чтение атомарного счетчика во время его обновления также
// возможно, используя функцию `atomic.LoadUint64`.
fmt.Println("ops:", ops)
}