Go言語における並行リソース競合の解決方法
Go言語で並行リソース競合を解決するには、以下のような手法があります。
- ネイティブの日本語で言い換える:sync.Mutex
- ロック
- 解除する
package main
import (
"fmt"
"sync"
)
var counter int
var mutex sync.Mutex
func main() {
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println(counter)
}
func increment(wg *sync.WaitGroup) {
mutex.Lock()
counter++
mutex.Unlock()
wg.Done()
}
- ネイティブの日本語による言い換え: 同期付き読み書きロック
- 排他ロック取得
- natively
- ロック()
- アンロックする
package main
import (
"fmt"
"sync"
)
var counter int
var rwMutex sync.RWMutex
func main() {
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println(counter)
}
func increment(wg *sync.WaitGroup) {
rwMutex.Lock()
counter++
rwMutex.Unlock()
wg.Done()
}
- 同時に
- AddInt32()
- AddInt64()
- AddUint32()
- AddUint64()
- CompareAndSwapInt32()
- CompareAndSwapInt64()
package main
import (
"fmt"
"sync"
"sync/atomic"
)
var counter int32
func main() {
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println(atomic.LoadInt32(&counter))
}
func increment(wg *sync.WaitGroup) {
atomic.AddInt32(&counter, 1)
wg.Done()
}
これら手法はすべて排他制御におけるリソース争奪問題を有効的に解決できますが、具体的にどの手法を採用するかは具体的なニーズとシーンによって異なります。