Основным механизмом управления состоянием в Go является
связь по каналам. Мы видели это, например, с пулами воркеров.
Есть несколько других вариантов управления состоянием.
Здесь мы рассмотрим использование пакета |
|
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)
|
Для атомарного увеличения счетчика мы
используем AddUint64, присваивая ему адрес
памяти нашего счетчика |
go func() {
for c := 0; c < 1000; c++ {
|
atomic.AddUint64(&ops, 1)
}
wg.Done()
}()
}
|
|
Ждем пока завершатся горутины. |
wg.Wait()
|
Теперь доступ к |
fmt.Println("ops:", ops)
}
|
Мы ожидаем получить ровно 50 000 операций. Если бы
мы использовали неатомарный |
$ go run atomic-counters.go
ops: 50000
|
Далее мы рассмотрим мьютексы, еще один способ управления состоянием. |
Следующий пример: Мьютексы (Mutexes).