一尘不染

如何从并发映射写入中恢复?

go

如何从“并发映射读取和映射写入”的运行时恐慌中恢复?通常,恢复时的延迟似乎不起作用。这是为什么?

我知道您不应该在并发上下文中使用地图,但是仍然:如何在此处恢复?

例:

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)
}

请添加恢复代码。:)


阅读 148

收藏
2020-07-02

共1个答案

一尘不染

恢复在这里不起作用,因为您遇到的不是紧急状态。

Go
1.6向
运行时添加了轻量级的并发滥用地图检测功能:

运行时增加了轻巧,尽力而为的检测并发滥用地图的功能。与往常一样,如果一个goroutine正在写入地图,则其他goroutine不应同时读取或写入地图。
如果运行时检测到这种情况,它将打印诊断并使程序崩溃。 找出更多有关该问题的最佳方法是在“
种族检测器”下运行该程序,这将更可靠地识别种族并提供更多详细信息。

您遇到的是运行时 故意崩溃 ,这不是panic()调用的结果导致recover()延迟函数中的调用可能停止。

除了阻止并发滥用地图外,您无能为力。如果您以这种方式离开应用程序并且不会崩溃,那么您可能会在运行时遇到神秘的,未定义的行为。

2020-07-02