如何从“并发地图读取和地图写入”的运行时恐慌中恢复?恢复的通常延迟似乎不起作用。那是为什么?
我知道你不应该在并发环境中使用地图,但仍然:如何在这里恢复?
示例:
package main
import "time"
var m = make(map[string]string)
func main() {
go func() {
for {
m["x"] = "foo"
}
}()
go func() {
for {
m["x"] = "foo"
}
}()
time.Sleep(1 * time.Second)
}
请添加恢复代码。 :)
答案 0 :(得分:14)
恢复在这里不起作用,因为你所经历的并不是一个惊慌失措的状态。
Go 1.6 added轻量级并发滥用地图检测到运行时:
运行时添加了轻量级,尽力而为的并发滥用映射的方法。和往常一样,如果一个goroutine正在写一张地图,那么其他任何goroutine都不应该同时读取或写入地图。 如果运行时检测到这种情况,它会打印诊断并使程序崩溃。了解问题的最佳方法是在race detector下运行程序,这将更加可靠确定比赛并提供更多细节。
您遇到的是运行时的故意崩溃,这不是panic()
调用导致延迟函数中recover()
调用可能停止的结果。
除了防止并发滥用地图之外,你无能为力。如果您将这样离开您的应用程序并且它不会崩溃,您可能会在运行时遇到神秘的,未定义的行为。
答案 1 :(得分:1)
请勿使用互斥锁格式包sync来保护您的代码。
package main
import (
"sync"
"time"
)
var m = make(map[string]string)
var l = sync.Mutex{}
func main() {
go func() {
for {
l.Lock()
m["x"] = "foo"
l.Unlock()
}
}()
go func() {
for {
l.Lock()
m["x"] = "foo"
l.Unlock()
}
}()
time.Sleep(1 * time.Second)
}