【Golang】他のスレッドが読み取りしている最中にRWMutex.Lock()をかけても待機しない
表題のとおりだが、goroutineでマルチスレッド処理する場合、スレッドセーフではない値に読み書きする場合はRWMutex等を使って排他制御 (ロック) する必要がある。この際、Aスレッドが読み取り専用でBスレッドが書き込み専用だとすると、Aスレッドではロックが必要なのか確認したかった。結論から言うと必要。
これはつまり、他のスレッドが排他制御をかけずに読取している最中に、他のスレッドが読書排他制御を掛けた場合、読み取りの終わりを待ってから排他制御をかけるのか、あるいは即座に排他制御をかけて書き込み始めるのかに帰結する。これは後者、つまり読み取りの終わりを待たないことがわかった
パニックする
package main import ( "time" "sync" "fmt" ) type st struct { sync.RWMutex m map[string]string } func main() { s := st{m:map[string]string{}} go func() { for { time.Sleep(1) s.Lock() s.m["a"] = "string" s.Unlock() } }() for { time.Sleep(1) fmt.Println(s.m["a"]) } }
パニックしない
package main import ( "time" "sync" "fmt" ) type st struct { sync.RWMutex m map[string]string } func main() { s := st{m:map[string]string{}} go func() { for { time.Sleep(1) s.Lock() s.m["a"] = "string" s.Unlock() } }() for { time.Sleep(1) s.RLock() fmt.Println(s.m["a"]) s.RUnlock() } }