同時進行のプログラミングを行う sync.Once
sync.Once
ある動作が一度だけ実行されることを保証するために使用され、設定の初期化などシングルインスタンスパターンで使用することができる。init() 関数も一度だけ実行されることが分かっていますが、これは
main()
関数を使用します。コード実行中に一度だけアクションを実行したい場合は
sync.Once
で、その使い方を説明します。
まず、次のコードから始めましょう。
package main
import (
"fmt"
"sync"
)
func main() {
var num = 6
var once sync.Once
add_one := func() {
num = num + 1
}
minus_one := func() {
num = num - 1
}
once.Do(add_one)
fmt.Printf("The num: %d\n", num)
once.Do(minus_one)
fmt.Printf("The num: %d\n", num)
}
実装結果です。
数字:7
数字:7
sync.Once
型は
Do
メソッドは、1つのパラメータのみを受け入れ、型は
func()
は、引数宣言も結果宣言もない関数です。
Do
メソッドは、最初に呼び出されたときに渡された関数を一度だけ実行し、他の関数は実行しません。上の例では、渡された関数が異なっていても、最初に渡された関数のみが実行されます。もし一度だけ実行される関数が複数ある場合は、それぞれの関数に
sync.Once
型の値
func main() {
var num = 6
var once1 sync.Once
var once2 sync.
add_one := func() {
num = num + 1
}
minus_one := func() {
num = num - 1
}
once1.Do(add_one)
fmt.Printf("The num: %d\n", num)
once2.Do(minus_one)
fmt.Printf("The num: %d\n", num)
}
sync.Once
型は構造体型であり、その名称は
done
の
uint32
型フィールドと、相互に排他的なロック
m
.
type Once struct {
done uint32
m Mutex
m Mutex}
done
フィールドの値は0または1のみとすることができる。
Do
メソッドの最初の呼び出しが完了した後に
done
doneの値は1に変更されます。 doneの値には、4バイトの
uint32
型を使用して、その操作がアトミックな操作であることを確認するために
atomic.LoadUint32
関数でその値を取得し、それが1であれば関数を実行せずに直接返します。
0の場合、Doメソッドは直ちにフィールドmをロックします。ここでロックが適用されない場合、複数の
goroutine
がすべて 0 のときに Do メソッドを同時に実行すると、関数が実行されるため
Once
は同時並行的に安全です。
ロックした後、再び
done
フィールドを生成し、条件を満たした場合、入力された関数を実行し、アトミック操作関数
atomic.StoreUint32
は、その
done
の値を 1 に設定します。
以下はOnceのソースコードです。
func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 0 {
o.doSlow(f)
}
}
func (o *Once) doSlow(f func()) {
o.m.Lock()
defer o.m.Unlock()
if o.done == 0 {
defer atomic.StoreUint32(&o.done, 1)
f()
}
}
ソースコードは非常にクリーンで、GoFデザインパターンのシングルトン・パターンに非常によく似ています。
今回の記事は、Goの並行プログラミングsync.Onceについてです。Goのsync.Onceについては、過去の記事を検索するか、引き続き以下の記事を閲覧してください。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン