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言語で使えるORMライブラリ

1 はじめに2 ORMライブラリ2.1 GORM2.2 SQLBoiler3 GORMを使ってみる3.1 導入3.2 migration3.3 insert3.4 select3.5 update3. ...

laravel logo

LaravelのFacade(ファサード)とは? 何気なく使用していた裏側の仕組みを解説!

1 はじめに1.1 Facadeを使用しているクラス2 Facadeの仕組み3 Facadeの作成3.1 サンプルコードに必要な実装3.2 Serviceの作成3.3 Facadeクラスの作成3.4 ...

rails

RailsでS3に画像をアップロードする

1 はじめに2 今回やりたいこと3 下準備3.1 ImageMagickをインストールする3.2 Gemをインストールする4 レコード生成時にファイルを指定してアップロードする4.1 アップローダを作 ...

rails

deviseを使ってユーザ登録フォームを作る

1 はじめに1.1 前提条件2 deviseについて2.1 deviseとは2.2 deviseでできること3 登録処理の実装3.1 Gemのインストール3.2 deviseのインストール3.3 デフ ...

Go言語

goroutineとchannelとContext

1 はじめに2 並行処理と並列処理3 goroutine4 channel4.1 channelからデータ受信4.2 for-range でのデータ受信4.3 複数のchannelを受信4.4 buf ...

フォロー

blog-page_side_responsive

2020年4月
 1234
567891011
12131415161718
19202122232425
2627282930  

アプリ情報

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