How to recover from concurrent map writes?

你。 提交于 2019-11-26 21:55:10

问题


How do you recover from a runtime panic on a "concurrent map read and map write"? The usual defer with recover doesn't seem to work. Why is that?

I know that you are not supposed to use maps in concurrent contexts, but still: how to recover here?

Example:

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

Please add recovery code. :)


回答1:


Recovering doesn't work here because what you experience is not a panicing state.

Go 1.6 added a lightweight concurrent misuse of maps detection to the runtime:

The runtime has added lightweight, best-effort detection of concurrent misuse of maps. As always, if one goroutine is writing to a map, no other goroutine should be reading or writing the map concurrently. If the runtime detects this condition, it prints a diagnosis and crashes the program. The best way to find out more about the problem is to run the program under the race detector, which will more reliably identify the race and give more detail.

What you experience is an intentional crash by the runtime, it's not the result of a panic() call that a recover() call in a deferred function could stop.

There's nothing you can do to stop that except prevent the concurrent misuse of maps. If you would leave your app like that and it wouldn't crash, you could experience mysterious, undefined behavior at runtime.




回答2:


Do not recover, guard your code with mutexes form package 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)
}


来源:https://stackoverflow.com/questions/39288741/how-to-recover-from-concurrent-map-writes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!