同時アクセスのあるプログラムでマップを使用する場合、関数でミューテックスを使用して値を読み取る必要はありますか?
6 に答える
複数のリーダー、ライターは大丈夫ではありません:
https://groups.google.com/d/msg/golang-nuts/HpLWnGTp-n8/hyUYmnWJqiQJ
一人の作家、読者は大丈夫ではありません。(それ以外の場合、マップはあまり良くありません。)
それ以外の場合、少なくとも1つのライターがあり、ライターまたはリーダーが少なくとも1つある場合は、すべてのリーダーとライターが同期を使用してマップにアクセスする必要があります。これにはミューテックスが正常に機能します。
sync.Map
2017年4月27日をもってGo masterに統合されました。
これは私たちが待ち望んでいた並行マップです。
数日前、このreddit スレッドであなたの質問に答えました。
Go では、マップはスレッドセーフではありません。また、たとえば、同じデータを (同時に) 書き込んでいる別のゴルーチンが存在する可能性がある場合は、データを読み取る場合でもロックが必要です。
コメントの明確化から判断すると、セッター関数も存在する予定です。質問への答えは「はい」です。読み取りをミューテックスで保護する必要があります。RWMutexを使用できます。例として、私が書いたテーブル データ構造 (舞台裏でマップを使用) の実装のソース(実際には reddit スレッドにリンクされているもの) を見ることができます。
同時実行の痛みを処理するために、concurrent-mapを使用できます。
// Create a new map.
map := cmap.NewConcurrentMap()
// Add item to map, adds "bar" under key "foo"
map.Add("foo", "bar")
// Retrieve item from map.
tmp, ok := map.Get("foo")
// Checks if item exists
if ok == true {
// Map stores items as interface{}, hence we'll have to cast.
bar := tmp.(string)
}
// Removes item under key "foo"
map.Remove("foo")