Go で複数のスレッドが同時に動作するシナリオでは、安全なデータ アクセスを確保することが重要です。この記事では、メイン スレッドがスレッドの安全性を損なうことなくワーカー スレッドからのデータ収集を必要とするシナリオについて説明します。
シナリオ
メイン スレッドは複数のワーカー スレッドを作成し、それぞれが実行されます。独自のゴルーチンと定期的な間隔で反復回数を増加させます。メイン スレッドは、10 秒ごとにワーカーから反復回数を収集し、統合された統計を表示することを目的としています。
質問
メイン スレッドは、個々のスレッドが書き込みを行っている間のみ読み取りを行うとすると、値に直接アクセスしても安全ですか?これを効果的に実装するにはどうすればよいですか?
回答
同期せずに異なるスレッドから値を直接読み取ることは、未定義の動作を示す可能性があるため、Go では本質的に安全ではありません。データの整合性を確保するには、何らかの形式の同期が必要です。
実装に関する考慮事項
提案されたソリューションでは、sync.RWMutex を利用して共有データを保護します。ワーカーが反復回数に書き込むと書き込みロックを取得し、メインスレッドが読み込むと読み取りロックを取得します。
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) incIter() { w.iterMu.Lock() w.iter++ w.iterMu.Unlock() }
また、以下に示すように、sync/atomic パッケージを使用してスレッドセーフなデータ変更を管理することもできます。 code:
sync/atomic を使用したコード例
type Worker struct { iter int64 } func (w *Worker) Iter() int64 { return atomic.LoadInt64(&w.iter) } func (w *Worker) incIter() { atomic.AddInt64(&w.iter, 1) }
以上がGo で複数のゴルーチンから値を安全に読み取るにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。