[Golang/Go言語]sync.Lockerを使って変数の排他制御を学びましょう!

golang

こんにちは。KOUKIです。

とあるWeb系企業で、Goエンジニアをやっています。

今日は、goのsync.Lockerを使って、変数管理の方法を学びましょう。

シチュエーション

口座か何かの入出金処理を考えてみましょう。

いく人かのグループが以下の図のように共通口座のお金をやりとりします。

そして、最終的な結果(TotalAccounts)は、処理の初期値と変わらないようにしたい、そんなプログラムを実装したいと思います。

一見簡単そうに見えますが、変数(ここではTotalAccounts)の排他制御が必要になるので、少し難しいかもしれません。

sync.Locker

sync.Lockerは、変数の排他制御を提供する便利機能です。

以下のインターフェースを提供しています。

同じく排他制御機能を提供するsync.Mutexもあるので、合わせて覚えておいてください。

Mutexには、Lock/Unlockメソッドが提供されています。しかし、sync.Lockerには提供されていないので、自分で実装する必要がありますね。

実装

プロジェクトの作成

以下のファイルを用意してください。

spin_lock.go

先ほどお伝えしたとおり、sync.LockerのLock/Unlockメソッドを実装します。

golangでは、Interfaceに定義した関数(ここではLock/Unlock)をメソッドとして定義するとInterfaceを実装したことになります。

multi_ledger.go

まず、必要なパッケージを読み込みましょう。

次に、固定値の定義です。

accountの貸し借り処理を実装します。

上記のLock、Unlockが肝です。これにより排他制御を行なっています。

rand.Intnは、指定した数値内の値をランダムで返却します。

最後にmain関数です。

コメントにMutexバージョンも記載しておきました。Lockerと切り替えられるようになっています。

前述の通り、MutexもLockerもLock/Unlockメソッドを実装しているので、「locks *[totalAccounts]sync.Locker」の引数として渡すことができます(Interface要件を満たすため)。

プログラムを実行してみましょう。

いい感じですね。

それでは、Lock/Unlock関数の呼び出しをコメントアウトしましょう。

プログラムを実行します。

値がバラけてしまいましたね。排他制御が実装できていることになります。

おわりに

排他制御は実務でも重要になるものです。

そのため、MutexやLockerを利用する頻度は高いでしょう。

個人的にはMutexしか使っていませんが^^;

それでは、また!

Go記事まとめ

Go記事をまとめます。

ソースコード

spin_lock.go

multi_ledger.go

コメントを残す