golang可能的panic场景
约 491 字大约 2 分钟
2025-05-21
golang 开发过程中, 会有很多并发不安全的场景, 如果没有合适的处理, 很容易会导致panic, 下面是一些常见的场景
map相关
并发读写
map 并发读取不会出现问题, 并发读+写会panic, 并发写+写也会panic, 冲突如下
并发操作 | 读 | 写 |
---|---|---|
读 | 允许 | panic |
写 | panic | panic |
首先, map 是 非并发安全
的, 并发读写会panic, 但是不是一定会panic, 所以不要赌小概率事件, 示例如下:
func mapModify() {
mapData := map[string]any{
"key": "value",
}
wg := &sync.WaitGroup{}
wg.Add(6)
for i := 0; i < 3; i++ {
go func() {
defer wg.Done()
fmt.Println(mapData["key"])
}()
go func() {
defer wg.Done()
mapData["key"] = time.Now()
}()
}
wg.Wait()
}
上面这段代码, 本地执行, 有很大几率不会panic, 但是并不是说代码没问题, 上面代码为了演示, 简化了逻辑, 在工程化场景下, 逻辑复杂, 高频读取, 基本是会panic, 包的. 将上述逻辑调整成如下代码, 模拟高频读写:
func mapModify() {
mapData := map[string]any{
"key": "value",
}
wg := &sync.WaitGroup{}
wg.Add(6)
for i := 0; i < 3; i++ {
go func() {
defer wg.Done()
for {
fmt.Println(mapData["key"])
}
}()
go func() {
defer wg.Done()
for {
mapData["key"] = time.Now()
}
}()
}
wg.Wait()
}
上述代码会稳定报错: fatal error: concurrent map writes
, 代表了map并发读写导致panic
未初始化map写
func opNilMap() {
var mapData map[string]any
fmt.Println(mapData["name"])
mapData["name"] = "value"
}
上述代码, 仅声明map, 但是未初始化, 访问会有问题, 但是会发现, 读取是正常的, 说明 NIL Map是支持数据读取的, 返回对应value的零值
, 但是, 设置数据的时候, 会产生panic: panic: assignment to entry in nil map