[Go言語]Sync.CondのSignalで特定の条件に達成するまでプログラムを待つ処理を実装しよう

こんにちは。KOUKIです。

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

皆さんは、syncパッケージのSignalメソッドを使ってますでしょうか。

僕はこの存在自体知らなかったですw

ただ、最近、Udemyのコースでこのメソッドの存在を知ったので、紹介したいと思います。

これを使うと「Gorutineの処理をとある状態になるまで待つ」などの処理が書けるようになるため、結構プログラミングの幅が広がると思います。

サンプルコード

まず、Signalメソッド実装前のサンプルコードを以下に記載します。

sharedRsc」変数は、goroutine間で読み書きする共通変数です。

処理の流れとしては、main goroutineがsharedRsc変数に「foo」を書き込むまで、Wait(プログラムの停止)をさせたいと考えています。

しかし、現実は以下のようになっています。

「foo」が表示されているのでこのプログラムは一見問題なさそうに見えます。しかし、Waitがやたら出力され無駄な処理が実行されていることがわかります。

sync.Condを使ってみよう

こんな状況の時、誰もがこう感じると思います。

fooが書き込まれたらシグナル(Signal)送って、プログラムを実行できないかな

できます。

sync.Condを使えば、できます(大切なことなので、2回書きました)。

排他制御準備

sync.Condを使うために、まずは、NewCondします。

NewCondするために、最初にMutexを宣言してそれを引数に渡しています。これで排他制御の準備が完了です。

Mutexについては、以下の記事をどうぞ。

書き込み/読み込み制御

次に、書き込みと読み込みを制御します。

この辺りの使い方は、Mutexと大体同じです。書き込み、読み込みが発生する処理の前で、Lock/UnLockをするだけです。sync.Condは内部に「Locker」を持っていて、それがLock/UnLockメソッドを実装してます。

この状態でプログラムを送ると以下のように「Wait….」がずっと表示される状態になります。

Signalを待とう

Waitメソッドを使って、Signalが送られてくるまで待つ処理を追加します。

プログラムを実行するとエラーが発生します。

いつまでもSignalが送られてこないので、Waitが怒ったようです。

Signalを送る

sharedRsc変数に「foo」が書き込まれたらSignalを送りたいので、以下のように書き込み処理の直後にSignalメソッドを追加します。

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

OKですね。これで完了です。

おわりに

Signalメソッドを使えば、結構簡単にgoroutineを制御することができそうですね。

手軽だからこそ、バグも発生しそうではありますが^^;

それでは、また!

Go言語まとめ

まとめ記事


プログラム

コメントを残す