Golang安全讀寫共享變量的方式詳解
1. 使用互斥鎖(Mutex)
互斥鎖(Mutex)是一種常用的同步原語,用于防止多個協(xié)程同時訪問共享資源。
package main
import (
"fmt"
"sync"
)
var (
counter int
mutex sync.Mutex
)
func increment(wg *sync.WaitGroup) {
defer wg.Done()
mutex.Lock()
counter++
mutex.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println("Final Counter:", counter)
}2. 使用channel
Go語言的核心理念之一就是“不通過共享內(nèi)存來通信,而是通過通信來共享內(nèi)存”。我們可以通過創(chuàng)建一個channel,然后通過發(fā)送和接收消息的方式來讀寫共享變量。這種方式在處理并發(fā)問題時非常有用,因?yàn)?code>channel本身就提供了安全性。
package main
import (
"fmt"
)
func increment(counter chan int, done chan bool) {
for i := 0; i < 1000; i++ {
value := <-counter
value++
counter <- value
}
done <- true
}
func main() {
counter := make(chan int, 1)
counter <- 0
done := make(chan bool)
for i := 0; i < 10; i++ {
go increment(counter, done)
}
for i := 0; i < 10; i++ {
<-done
}
fmt.Println("Final Counter:", <-counter)
}3. 讀寫鎖(sync.RWMutex)
如果程序中的讀操作遠(yuǎn)多于寫操作,那么使用讀寫鎖可能會比互斥鎖更有效率。讀寫鎖允許多個協(xié)程同時讀取變量,但是只允許同一時刻只有一個協(xié)程進(jìn)行寫入操作。
package main
import (
"fmt"
"sync"
)
var (
counter int
rwMutex sync.RWMutex
)
func read(wg *sync.WaitGroup) {
defer wg.Done()
rwMutex.RLock()
fmt.Println("Counter:", counter)
rwMutex.RUnlock()
}
func write(wg *sync.WaitGroup) {
defer wg.Done()
rwMutex.Lock()
counter++
rwMutex.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go read(&wg)
}
for i := 0; i < 10; i++ {
wg.Add(1)
go write(&wg)
}
wg.Wait()
}4. 原子操作(sync/atomic包)
對于一些簡單的數(shù)值或者布爾類型,我們可以使用原子操作來讀寫共享變量。
package main
import (
"fmt"
"sync"
"sync/atomic"
)
var counter int64
func increment(wg *sync.WaitGroup) {
defer wg.Done()
atomic.AddInt64(&counter, 1)
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println("Final Counter:", counter)
}5. sync.Once
如果共享變量只需要被初始化一次,可以使用sync.Once來確保初始化的并發(fā)安全性。
package main
import (
"fmt"
"sync"
)
var (
once sync.Once
initValue int
)
func initialize() {
fmt.Println("Initializing...")
initValue = 42
}
func doSomething() {
once.Do(initialize)
fmt.Println("Value:", initValue)
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
doSomething()
}()
}
wg.Wait()
}最后給大家推薦一個LinuxC/C++高級架構(gòu)系統(tǒng)教程的學(xué)習(xí)資源與課程,可以幫助你有方向、更細(xì)致地學(xué)習(xí)C/C++后端開發(fā),具體內(nèi)容請見 https://xxetb.xetslk.com/s/1o04uB
到此這篇關(guān)于Golang安全讀寫共享變量的方式的文章就介紹到這了,更多相關(guān)Golang安全讀寫共享變量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang NewRequest/gorequest實(shí)現(xiàn)http請求的示例代碼
本文主要介紹了golang NewRequest/gorequest實(shí)現(xiàn)http請求的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
如何在Go中將[]byte轉(zhuǎn)換為io.Reader
本文主要介紹了如何在Go中將[]byte轉(zhuǎn)換為io.Reader,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12
Go 通過結(jié)構(gòu)struct實(shí)現(xiàn)接口interface的問題
這篇文章主要介紹了Go 通過結(jié)構(gòu)struct實(shí)現(xiàn)接口interface的問題,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-10-10
Golang觀察者模式優(yōu)化訂單處理系統(tǒng)實(shí)例探究
當(dāng)涉及到訂單處理系統(tǒng)時,觀察者設(shè)計模式可以用于實(shí)現(xiàn)訂單狀態(tài)的變化和通知,在這篇文章中,我們將介紹如何使用Golang來實(shí)現(xiàn)觀察者設(shè)計模式,并提供一個基于訂單處理系統(tǒng)的代碼示例2024-01-01
基于golang的簡單分布式延時隊(duì)列服務(wù)的實(shí)現(xiàn)
這篇文章主要介紹了基于golang的簡單分布式延時隊(duì)列服務(wù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02

