異なるスレッドからの値の読み取りは安全ですか?
Go では、複数の goroutine が関与する場合、特に次の場合に値に安全に同時アクセスするには同期が必要です。少なくとも 1 つが書き込みを実行します。特定のシナリオでは、未定義の動作を防ぐために同期を実装する必要があります。
推奨されるアプローチ: ミューテックスの利用
チャネルは、メッセージ パッシングのオプションですが、メインスレッドでのメッセージ取得に同期が必要なため、不必要に複雑になります。代わりに、読み取り/書き込みミューテックス (sync.RWMutex) を使用することをお勧めします。これらのロックは、変更操作 (ワーカー) のロック取得とステータス取得 (メイン スレッド) の読み取り専用アクセスを強制することでデータを保護します。
実装例
type Worker struct { iterMu sync.RWMutex iter int } func (w *Worker) Iter() int { w.iterMu.RLock() defer w.iterMu.RUnlock() return w.iter } func (w *Worker) setIter(n int) { w.iterMu.Lock() w.iter = n w.iterMu.Unlock() }
このアプローチにより、反復回数を変更するワーカーが書き込みロックを取得し、その回数を読み取るメインスレッドが読み取りロックを取得することが保証されます。 locks.
代替: アトミック操作
sync/atomic パッケージは、整数などの特定のデータ型を同期なしで変更できるアトミック操作を提供します。読み取りおよび変更操作をアトミック関数に制限することで整合性を確保します。
type Worker struct { iter int64 } func (w *Worker) Iter() int64 { return atomic.LoadInt64(&w.iter) } func (w *Worker) setIter(n int64) { atomic.StoreInt64(&w.iter, n) } func (w *Worker) incIter() { atomic.AddInt64(&w.iter, 1) }
このアプローチはより単純な同期メカニズムを提供しますが、特定のデータ型にのみ適用できることに注意してください。
これらの方法の 1 つを使用すると、異なるスレッドのワーカーから値を安全に読み取ることができ、データの整合性が保証され、未定義の動作が回避されます。
以上がGo でさまざまな goroutine から値を安全に読み取るにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。