こんにちは。Tomoyuki(@tomoyuki65)です。
Go言語(Golang)でgoroutine(ゴールーチン)から共有リソースに対して読み書きをする必要がある場合、何も考慮しなければ競合状態になってエラーが発生する可能性があるので注意が必要です。
そういう場合はmutex(ミューテックス)を使って排他制御をすることで、競合状態を避けることが可能です。
Go言語(Golang)はgoroutine(ゴールーチン)で並行処理が可能!
こんにちは。Tomoyuki(@tomoyuki65)です。 Go言語(Golang)ではgoroutine(ゴールーチン)を使うことによって並行処理が可能なため、上手く使えばパフォーマンス改善に繋がります! ※プログラムは通常一行ずつ処理...
Go言語(Golang)のchannel(チャネル)型でgoroutine(ゴールーチン)間のデータを送受信!
こんにちは。Tomoyuki(@tomoyuki65)です。 Go言語(Golang)にはchannel(チャネル)型というのがあり、これを使うことでgoroutine(ゴールーチン)間のデータを送受信できます。 Go言語(Golang)の...
Go言語(Golang)のmutex(ミューテックス)でgoroutine(ゴールーチン)の排他制御を知る!
mutex(ミューテックス)を使ったサンプルコードは次の通りです。
package main
import (
"fmt"
"time"
"sync"
)
// カウンター用の変数を定義(共有リソース)
var counter int
// ミューテックスを定義
var mutex sync.Mutex
// カウントアップ用関数
func countUp(wg *sync.WaitGroup) {
defer wg.Done()
// カウンターを10回カウントアップさせる
for i := 0; i < 10; i++ {
// mutexをロックし、他のgoroutineがカウンターにアクセスできないようにする
mutex.Lock()
// カウンターをインクリメント
counter++
// mutexのロックを解除
mutex.Unlock()
// シミュレート用として10ms経過させる
time.Sleep(time.Millisecond * 10)
}
}
func main() {
// WaitGroupを10個定義
var wg sync.WaitGroup
wg.Add(10)
// goroutineを10個起動し、カウンターをカウントアップさせる
for i := 0; i < 10; i++ {
go countUp(&wg)
}
wg.Wait()
fmt.Println("カウンターの最終値:", counter)
}
実行結果は以下のようになります。
カウンターの最終値: 100
上記の例ではmutexを使わなくてもカウンターの最終値はかわりませんが、今回は基本的な使い方について示しました。
また、mutexを多用するとパフォーマンスにも影響があるため、goroutineで競合状態が発生しそうであり、かつパフォーマンスの影響も大丈夫な場合に使うのが最適なので、その点は注意しましょう。
最後に
今回はmutex(ミューテックス)についてご紹介しました。
goroutineのような非同期処理を使う場合は排他制御が必要になる可能性があるため、mutexの使い方についても覚えておきましょう。
コメント