概念簡介
Go語言中最主要的狀態管理方式是通過通道間的溝通來完成的,我們
在工作池的例子中碰到過,但是還是有一
些其他的方法來管理狀態的。這裏我們將看看如何使用 `sync/atomic`
包在多個 Go 協程中進行原子計數 。
例程代碼
package main
import "fmt"
import "time"
import "sync/atomic"
import "runtime"
func main() {
// 我們將使用一個無符號整型數來表示(永遠是正整數)這個計數器。
var ops uint64 = 0
// 為了模擬並發更新,我們啟動 50 個 Go 協程,對計數
// 器每隔 1ms (譯者注:應為非準確時間)進行一次加一操作。
for i := 0; i < 50; i++ {
go func() {
for {
// 使用 `AddUint64` 來讓計數器自動增加,使用
// `&` 語法來給出 `ops` 的內存地址。
atomic.AddUint64(&ops, 1)
// 允許其它 Go 協程的執行
runtime.Gosched()
}
}()
}
// 等待一秒,讓 ops 的自加操作執行一會。
time.Sleep(time.Second)
// 為了在計數器還在被其它 Go 協程更新時,安全的使用它,
// 我們通過 `LoadUint64` 將當前值的拷貝提取到 `opsFinal`
// 中。和上麵一樣,我們需要給這個函數所取值的內存地址 `&ops`
opsFinal := atomic.LoadUint64(&ops)
fmt.Println("ops:", opsFinal)
}
執行&輸出
# 執行這個程序,顯示我們執行了大約 40,000 次操作
$ go run atomic-counters.go
ops: 40200
# 下麵,我們將看一下互斥鎖——管理狀態的另一個工具
課程導航
學習上一篇:Go語言教程:速率限製 學習下一篇:Go語言教程:互斥鎖
相關資料
本例程github源代碼:https://github.com/xg-wang/gobyexample/tree/master/examples/atomic-counters