BackEnd

Golangのsyncパッケージによる同期・排他制御

投稿日:2020年4月27日 更新日:

はじめに

以前にgoroutineとchannelとContextという記事を書きましたが、今回は channel を使用しないで並行処理の同期や排他制御を簡単に行える、 sync パッケージについて学習したいと思います。

sync.WaitGroup

sync.WaitGroup は複数の Goroutine の完了を待つことが出来ます。

sync.WaitGroup は複数の Goroutine の完了を待つことが出来ます。
sync.WaitGroup は基本的にはただのカウンタですが、カウンタがゼロになるまで処理を待つことができます。上記のコードだと Add(1) でカウンタをインクリメントし、 Done() でデクリメントしています。そして Wait() はカウンタがゼロになるまで待ちます。

sync.Mutex

channel 以外の方法で変数に対して異なる goroutine がアクセスしても、競合によるエラーが起きないようにするための機能です。

sync.Mutex の Lock 関数と Unlock 関数で排他ロックの取得と解除ができます。排他ロックなので、排他ロックを得た goroutine が存在する場合は、ロックを得ようとする他の goroutine は処理を待ち、以下のような結果になります。

sync.RWMutex

sync.RWMutex の Rlock 関数と Runlock 関数で共有ロックの取得と解除ができます。どういうことなのかというと、 Rlock 関数でロックを行なった goroutine 同士であれば処理を進めることができるようになります。また、共有ロックを得た goroutine が存在する場合は、排他ロックを取得しようとする goroutine は待ちます。

実行すると以下のようになります。

sync.Map

Go の map は goroutine で Read しているときに別の goroutine から Write してはいけないというルールがあります。これを行なってしまうと panic が起きてしまいます。例えば以下の処理を実行すると異常終了を起こします。

こちらに対応するには、上記の sync.Mutex を使うことで対応可能ですが、 sync.Map を使用することで、ロックの制御を気にせずに map を使用することができます。

sync.Once

sync.Once は関数を一度だけ実行するようにできます。

実行すると以下のようになります。

sync.Pool

sync.Pool はスレッドセーフなメモリプールです。使い方は、 sync.Pool 構造体を生成する時の New フィールドにオブジェクト生成の関数を指定します。必要時に New の関数が呼ばれます。あるスレッドで、 Get メソッドを呼び、もしプールに無かったら New 関数でオブジェクトを生成します。そして Get でオブジェクトを取得します。もしプールにオブジェクトが在れば、そのオブジェクトを返します。使い終わったら Put メソッドでプールに戻します。
これの繰り返しでオブジェクトをリサイクルすることが出来ます。また、スレッドセーフですので、スレッド間でメモリプールする事ができます。

実行すると以下のようになります。

さいごに

sync パッケージの紹介でしたがいかがでしょうか。一部機能にしか触れられておらず、これからも勉強していこうと思います。

おすすめ書籍

スターティングGo言語 (CodeZine BOOKS) Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る impress top gearシリーズ 改訂2版 みんなのGo言語

blog-page_footer_336




blog-page_footer_336




-BackEnd
-

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

Go言語

Go 1.19でGoDocに追加された機能

1 はじめに2 GoDocの機能追加2.1 セクションタイトル(Headings)2.2 リンク2.3 リスト2.4 パッケージの追加3 おまけ4 さいごに5 おすすめ書籍 はじめに 8月2日にGo ...

rails

Rails Developer Meetup に参加してきました【2日目】

1 はじめに2 Rails Developer Meetup3 テストのないレガシーなRailsアプリをリファクタした話3.1 なぜリファクタリングしたのか3.2 コードを3種類に分類する3.3 モデ ...

laravel logo

Laravel Sail 環境に Laravel Breeze を導入してみた

1 はじめに2 Laravel Sail とは3 Laravel Breeze とは4 Laravel Breeze のインストール4.1 Composer4.2 npm5 マイグレーション6 確認7 ...

laravel logo

コードでわかるLaravelのブラウザ認証

1 はじめに1.1 認証機能の概要2 Controller3 SessionGuard3.1 fireAttemptEvent3.2 retrieveByCredentials3.3 hasValid ...

Go言語

GoフレームワークGinでミドルウェアを使ってログインAPIを実装

1 はじめに2 ログインAPIの作成3 ログインのセッション管理4 ミドルウェア4.1 gin.Default()4.2 Logger4.3 Recovery4.4 sessions5 独自ミドルウェ ...

フォロー

blog-page_side_responsive

2020年4月
 1234
567891011
12131415161718
19202122232425
2627282930  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。