Связь через каналы является основным механизмом для
управления состоянием в Go. Это было показано в
примере с набором обработчиков.
Есть несколько других возможностей для управления
состоянием. Здесь мы увидим использование |
|
package main
|
|
import "fmt"
import "time"
import "sync/atomic"
import "runtime"
|
|
func main() {
|
|
Используем беззанковое целое число для счётчика, который всегда положителен. |
var ops uint64 = 0
|
Для имитации одновременных обновлений запустим 50 горутин и каждая будет увеличивать счётчик примерно раз в миллисекунду. |
for i := 0; i < 50; i++ {
go func() {
for {
|
Для атомарного увеличения счётчика
используем |
atomic.AddUint64(&ops, 1)
|
Продолжаем другие горутины |
runtime.Gosched()
}
}()
}
|
Ждём секунду для того, чтобы позволить накопиться операциям |
time.Sleep(time.Second)
|
Чтобы безопасно использовать счётчик в то время,
пока он обновляется другими горутинами, сделаем
копию текущего значения в |
opsFinal := atomic.LoadUint64(&ops)
fmt.Println("ops:", opsFinal)
}
|
Программа показывает, что было выполнено примерно 40 000 операций. |
$ go run atomic-counters.go
ops: 40200
|
Далее посмотрим на мьютексы — ещё один инструмент для управления состоянием. |
Следующий пример: Мьютексы (Mutexes).