атомарные счетчики
This commit is contained in:
parent
acb7585e84
commit
f627d67e1a
@ -34,7 +34,7 @@ Select
|
|||||||
Пулы воркеров (Worker Pools)
|
Пулы воркеров (Worker Pools)
|
||||||
WaitGroups
|
WaitGroups
|
||||||
Ограничение скорости (Rate Limiting)
|
Ограничение скорости (Rate Limiting)
|
||||||
Atomic Counters
|
Атомарные счетчики (Atomic Counters)
|
||||||
Mutexes
|
Mutexes
|
||||||
Stateful Goroutines
|
Stateful Goroutines
|
||||||
Sorting
|
Sorting
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
// The primary mechanism for managing state in Go is
|
// Основным механизмом управления состоянием в Go является
|
||||||
// communication over channels. We saw this for example
|
// связь по каналам. Мы видели это, например, с [пулами воркеров](worker-pools).
|
||||||
// with [worker pools](worker-pools). There are a few other
|
// Есть несколько других вариантов управления состоянием.
|
||||||
// options for managing state though. Here we'll
|
// Здесь мы рассмотрим использование пакета `sync/atomic`
|
||||||
// look at using the `sync/atomic` package for _atomic
|
// для _атомарных счетчиков_, к которым обращаются горутины.
|
||||||
// counters_ accessed by multiple goroutines.
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -15,38 +14,37 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
// We'll use an unsigned integer to represent our
|
// Мы будем использовать целое число без знака
|
||||||
// (always-positive) counter.
|
// для представления нашего (всегда положительного)
|
||||||
|
// счетчика.
|
||||||
var ops uint64
|
var ops uint64
|
||||||
|
|
||||||
// A WaitGroup will help us wait for all goroutines
|
// WaitGroup поможет нам подождать, пока все горутины
|
||||||
// to finish their work.
|
// завершат свою работу.
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
// We'll start 50 goroutines that each increment the
|
// Мы запустим 50 горутин, каждая из которых увеличивает
|
||||||
// counter exactly 1000 times.
|
// счетчик ровно в 1000 раз.
|
||||||
for i := 0; i < 50; i++ {
|
for i := 0; i < 50; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for c := 0; c < 1000; c++ {
|
for c := 0; c < 1000; c++ {
|
||||||
// To atomically increment the counter we
|
// Для атомарного увеличения счетчика мы
|
||||||
// use `AddUint64`, giving it the memory
|
// используем AddUint64, присваивая ему адрес
|
||||||
// address of our `ops` counter with the
|
// памяти нашего счетчика `ops` с префиксом `&`.
|
||||||
// `&` syntax.
|
|
||||||
atomic.AddUint64(&ops, 1)
|
atomic.AddUint64(&ops, 1)
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until all the goroutines are done.
|
// Ждем пока завершатся горутины.
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
// It's safe to access `ops` now because we know
|
// Теперь доступ к `ops` безопасен, потому что мы знаем,
|
||||||
// no other goroutine is writing to it. Reading
|
// что никакие другие горутины не пишут в него. Безопасное
|
||||||
// atomics safely while they are being updated is
|
// чтение атомарного счетчика во время его обновления также
|
||||||
// also possible, using functions like
|
// возможно, используя функцию `atomic.LoadUint64`.
|
||||||
// `atomic.LoadUint64`.
|
|
||||||
fmt.Println("ops:", ops)
|
fmt.Println("ops:", ops)
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
# We expect to get exactly 50,000 operations. Had we
|
# Мы ожидаем получить ровно 50 000 операций. Если бы
|
||||||
# used the non-atomic `ops++` to increment the counter,
|
# мы использовали неатомарный `ops++` для увеличения
|
||||||
# we'd likely get a different number, changing between
|
# счетчика, мы бы, вероятно, получили другое число,
|
||||||
# runs, because the goroutines would interfere with
|
# изменяющееся между прогонами, потому что горутины
|
||||||
# each other. Moreover, we'd get data race failures
|
# мешали бы друг другу. Более того, мы получим сбои
|
||||||
# when running with the `-race` flag.
|
# в гонке данных при работе с флагом -race.
|
||||||
$ go run atomic-counters.go
|
$ go run atomic-counters.go
|
||||||
ops: 50000
|
ops: 50000
|
||||||
|
|
||||||
# Next we'll look at mutexes, another tool for managing
|
# Далее мы рассмотрим мьютексы, еще один способ
|
||||||
# state.
|
# управления состоянием.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user