Goでmapがアトミックになっていない理由
Goの組み込みマップ型は同時アクセスするとレースコンディションが発生する。これはRussによると、
If there are other map changes happening at the same time, your code is unsafe and will crash, either from the race detector or from the map implementation’s own race detector. Adding an ‘atomic’ delete would require synchronizing every write and delete just in case there was a racing write, which would slow down all accesses. That’s why maps aren’t atomic in the first place.
とあって、マップをアトミックにするとパフォーマンスが劣化するためらしい。
なので組み込みの delete() は実際に削除したかどうかを返さないし、読み書きが競合するとパニックする。
競合がない場合、削除されたかどうかは以下のコードで代用できる。
if _, ok := m[key]; ok { delete(m, key)}読み込みと削除が競合する場合は、以下のように事前判定すると回避できる可能性はある。読み込みは同時に起きても問題ないので Lock しなくても良い。
Lock()if _, ok := m[key]; !ok { m[key] = value}Unlock()これで多くのケースは回避できると思うけれど、書き込み途中で同じキーを読むとどうなるんだろうか。ここでマップの競合が発生するなら完全な対策とはならない。