Go での「range」を使用したマップへの同時アクセス
Go ブログのエントリ「マップの動作」では、次の場合の同期の重要性を強調しています。マップに同時にアクセスします。ただし、 range キーワードを使用したマップの反復処理が「読み取り」フェーズを構成するのか「ターンオーバー」フェーズを構成するのか、またこのプロセス中に同時アクセスが許可されるかどうかは不明のままです。
for ループ内の range 式が評価されます。ループが始まる前に 1 回。これは、マップ値にアクセスできるのは 1 回だけであり、それ以降にマップに加えられた変更は反復には反映されないことを意味します。そのため、反復中にマップ自体が変更されない限り、同時アクセスは安全です。
スレッドの安全性を確保するには、ループに入る前にマップを読み取りロックし、各反復後にロックを解除する必要があります。これにより、この間、同時実行の goroutine がマップを変更するのを防ぎます。以下のコードは、この手法を示しています。
func IterateMapKeys(iteratorChannel chan int) error { testMapLock.RLock() defer testMapLock.RUnlock() for k, v := range testMap { testMapLock.RUnlock() someFunc() testMapLock.RLock() if someCond { return someErr } } return nil }
書き込みロックを保持しながら別の goroutine でマップを変更すると、安全な変更とその後のループ反復子による変更の監視が保証されます。
ただし、このロック メカニズムは同時アクセスを防止するだけであり、同時変更を防止するものではないことに注意することが重要です。同時変更は引き続き発生する可能性がありますが、現在の反復には影響しません。
以上が「range」反復中の Go マップへの同時アクセスは安全ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。