fatal error: concurrent map iteration and map write

dis: 0.2839182387773051
dis: 0.09663299157559467
dis: 1.2640838214822172
dis: 0.2725675930110564
fatal error: concurrent map iteration and map write
goroutine 26 [running]:
runtime.throw({0x432b38, 0xc000292000})
        c:/go/src/runtime/panic.go:1198 +0x76 fp=0xc00033d858 sp=0xc00033d828 pc=0x196416
runtime.mapiternext(0x48a620)
        c:/go/src/runtime/map.go:858 +0x4eb fp=0xc00033d8c8 sp=0xc00033d858 pc=0x16f8cb
main.echo3({0x48f558, 0xc00013e2a0}, 0x0)
---
さて、やっつけますか。
「mapの競合状態のはなし」のページを参考にさせて頂き、新しく作ったmapが悪さをしているとアタリをつけました。
で、当初、sync.Mutexでロックしていたのですが、デッドロックが発生してしまいました。
そこで、sync.RWMutexに変更したところ、デッドロックが発生しなくなりました。
―― というのは気のせいのようで、RWMutex でも メソッドにLock Unlockを使えば、Mutexと同じらしいので、たまたま偶然だったようです。
RWMutexのウリは、
RLock : 読み取り用のロック。RLock同士はブロックせず、Lockのみがブロックされる。解除時は RUnlockを使う
Lock : Mutexと同じロック。RLock, Lock双方をブロックする。
のようです。今回は、読み出し中に、書き込みや削除処理が走ることがあったのですが、読み出し場所が一箇所だけだったので、普通に、Lock, Unlockを使用することにしました。
これでサーバがダウンすることはなくなりました。
以上

2022/09,江端さんの技術メモ

Posted by ebata