如何从运行时恐慌中恢复“并发地图读取和地图写入”?通常的延迟和恢复似乎不起作用。为什么会这样呢?
我知道您不应该在并发的上下文中使用映射,但是仍然是:如何在这里恢复?
示例:
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)
}请添加恢复代码。:)
发布于 2016-09-02 09:39:56
恢复在这里不起作用,因为你所经历的不是一种顺从状态。
添加1.6是将映射检测到运行时的轻量级并发错误:
运行时增加了对并发误用映射的轻量级、最有效的检测。与往常一样,如果一个goroutine正在写入地图,则其他任何一个goroutine都不应该同时读取或写入该地图。如果运行时检测到这种情况,它会打印一个诊断并使程序崩溃。了解更多问题的最好方法是在种族检测器下运行程序,这样可以更可靠地识别种族并给出更详细的信息。
您所经历的是运行时有意造成的崩溃,这不是延迟函数中的panic()调用可以停止的结果。
除了防止同时滥用地图之外,没有什么可以阻止这一点。如果你像这样离开你的应用程序,并且它不会崩溃,你可能会在运行时体验到神秘的、未定义的行为。
发布于 2016-09-02 09:23:39
不要恢复,使用互斥表单包同步保护代码。
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)
}https://stackoverflow.com/questions/39288741
复制相似问题