sync.atomic
Golang 標(biāo)準(zhǔn)庫中的 sync/atomic 為開發(fā)者提供了對幾種簡單類型的原子操作函數(shù)。這些簡單類型包括int32, int64, uint32, uint64, uintptr, unsafe.Pointer峭沦。這些原子操作函數(shù)有以下5種:增減(Add),存儲(Store)榄鉴,載入(Load),交換(Swap)庆尘,比較并交換(CompareAndSwap)。
sync.atomic 與 sync.Mutex 對比
對比實驗源碼:
package main
import (
"fmt"
"sync"
"sync/atomic"
"time"
)
func main() {
test1()
test2()
}
// sync.Mutex
func test1() {
var wg sync.WaitGroup
var mutex sync.Mutex
count := int64(0)
t := time.Now()
for i := 0; i < 10000; i++ {
wg.Add(1)
go func(i int) {
mutex.Lock()
count++
wg.Done()
mutex.Unlock()
}(i)
}
wg.Wait()
fmt.Printf("test1 花費時間:%d, count的值為:%d \n", time.Now().Sub(t), count)
}
// sync.atomic
func test2() {
var wg sync.WaitGroup
count := int64(0)
t := time.Now()
for i := 0; i < 10000; i++ {
wg.Add(1)
go func(i int) {
atomic.AddInt64(&count, 1)
wg.Done()
}(i)
}
wg.Wait()
fmt.Printf("test2 花費時間:%d, count的值為:%d \n", time.Now().Sub(t), count)
}
對比實驗運行結(jié)果:
test1 花費時間:4514661, count的值為:10000
test2 花費時間:3361215, count的值為:10000
test1矛辕,test2 函數(shù)分別通過 sync.Mutex 和 sync.atomic 提供的原子操作函數(shù)實現(xiàn)對一個 int64 整數(shù)進行 10000 次多線程安全的加法運算付魔。通過實驗運行結(jié)果可知,sync.atomic 比 sync.Mutex 的執(zhí)行效率更高几苍。
sync.atomic 的實現(xiàn)原理大致是向 CPU 發(fā)送對某一個塊內(nèi)存的 LOCK 信號,然后就將此內(nèi)存塊加鎖妻坝,從而保證了內(nèi)存塊操作的原子性。這種對 CPU 發(fā)送信號對內(nèi)存加鎖的方式厘贼,比 sync.Mutex 這種在語言層面對內(nèi)存加鎖的方式更底層圣拄,因此也更高效。
除此之外庇谆,sync.atomic 避免了加鎖、解鎖的過程串述,一行代碼就可以完成線程安全操作哥攘,也比 sync.Mutex 更簡潔材鹦,代碼可讀性更強。