xmge
2021-11-01 20:00:29 +08:00
go map 的并发读写不会 panic ,而是直接调用 throw() 函数,导致程序退出,因此,如果程序中有可能出现 map 并发读写的情况,一定要处理掉,因为这种错误出现时,程序必然挂掉。
上述的结构是会出现问题的,map 并发读写的检查大概是:当读取某个 key 时会判断一个是否有协程在写的变量,如果有协程在写,则程序退出。
测试代码:
```go
package main
import "sync"
type Person struct {
Name string
}
func main() {
m := make(map[string]*Person)
wg := sync.WaitGroup{}
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 1000; i++ {
m["1"] = new(Person)
}
}()
}
wg.Wait()
}
```
报错信息:
```
fatal error: concurrent map writes
goroutine 21 [running]:
runtime.throw(0x1076c2d, 0x15)
/usr/local/go/src/runtime/panic.go:1117 +0x72 fp=0xc00002ff08 sp=0xc00002fed8 pc=0x102dd12
runtime.mapassign_faststr(0x1068c80, 0xc000098000, 0x1075205, 0x1, 0xc000056088)
/usr/local/go/src/runtime/map_faststr.go:211 +0x3f1 fp=0xc00002ff70 sp=0xc00002ff08 pc=0x100ea91
main.main.func1(0xc00009a000, 0xc000098000)
/Users/maning/go/tmp/hex.go:17 +0xac fp=0xc00002ffd0 sp=0xc00002ff70 pc=0x105f3ec
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1371 +0x1 fp=0xc00002ffd8 sp=0xc00002ffd0 pc=0x105bb81
created by main.main
/Users/maning/go/tmp/hex.go:14 +0x91
```