書籍勉強記を始めます & Golangの sync.Once についてメモ
始めに
オライリーの Go言語によるWebアプリケーション開発 を購入したので今日から少しずつ進め、そのレポートを連載したいと思います。
始めは1章ごとにメモや感想を書いて行こうかと思ったのですが、やってみたらそこそこのボリュームになりそうだったので進めながら随時小ネタとしてメモを書いて行くことにしました。割と基本的なこと(package紹介とか)や既出なことでも定着強化とこれからGolangを学ぶ人に向けて敢えて細かい粒度で書いて行こうと思います。
というわけで今日は第1章に登場する sync.Once
型について。
<追記> (手違いで古い下書きを投稿してしまった)
第1章について
この章ではWebSocketを使ったチャットアプリケーションを実装します。これは複数のユーザーが同時に接続し発言はリアルタイムに全員へ共有されます。
このアプリケーションの中ではHTMLテンプレートをコンパイルするのですが、これは何度も行う必要はないため sync.Once
型を使って複数のgoroutineが動作しても一度だけのコンパイルを行われ無駄が発生しないような動作とします。
<追記ここまで>
sync.Once 型
Golangには並行処理に関する強力な機能があります。これらは sync
パッケージにまとめられており非同期処理や排他制御等を行いたい時はよくお世話になることでしょう。
sync.Once
型には Do
というメソッドがありこれに func
を渡すことで実行することができますが、名前の通り一度しか実行されません(2回以上 Do
メソッドを呼んでも何も起こらない)。
検証コード
func main() { var once1 sync.Once once1.Do(ikkaime) // 1回目なので呼び出される once1.Do(nikaime) // 2回目なので呼び出されない var once2 sync.Once once2.Do(ikkaime) // 新しく生成された後の1回目なので呼び出される once2.Do(nikaime) // 2回目なので呼び出されない } func ikkaime() { fmt.Println("1回目だけ!") } func nikaime() { fmt.Println("2回目は実行されない!") }
結果
実際にGo Playgroundで実行してみて下さい。
sync.Once
型の once1
と once2
でそれぞれ1回目には ikkaime()
、2回目には nikaime()
という関数を2回ずつ呼び出していますが、どちらも1回目しか実行されていないことがわかるかと思います。
何らかの一度しか実行したくない性質のもの(初期化処理等)で有用です。