Golang fatal error: concurrent map read and map write

后端 未结 1 1785
有刺的猬
有刺的猬 2021-01-31 18:42

I\'m writing minecraft server in Go, when server is being stressed by 2000+ connections I get this crash:

fatal error: concurrent map read and map write/root/w
相关标签:
1条回答
  • 2021-01-31 19:06

    Generally speaking (without having access to the code where the error occurs) you have a few options. Here are two of them:

    sync.RWMutex

    Control access to the map with sync.RWMutex{}. Use this option if you have single reads and writes, not loops over the map. See RWMutex

    Here a sample with access control to someMap via someMapMutex:

    var (
        someMap      = map[string]string{}
        someMapMutex = sync.RWMutex{}
    )
    
    go func() {
        someMapMutex.Lock()
        someMap["key"] = "value"
        someMapMutex.Unlock()
    }()
    
    someMapMutex.RLock()
    v, ok := someMap["key"]
    someMapMutex.RUnlock()
    if !ok {
        fmt.Println("key missing")
        return
    }
    fmt.Println(v)
    

    syncmap.Map

    Use a syncmap.Map{} instead of a normal map. This map is already taking care of race issues but may be slower depending on your usage. syncmap.Map{}s main advantage lies with for loops. See syncmap

    var (
        someMap = syncmap.Map{}
    )
    
    go func() {
        someMap.Store("key", "value")
    }()
    
    v, ok := someMap.Load("key")
    if !ok {
        fmt.Println("key missing")
        return
    }
    fmt.Println(v)
    
    // with syncmap, looping over all keys is simple without locking the whole map for the entire loop
    someMap.Range(func(key, value interface{}) bool {
        // cast value to correct format
        val, ok := value.(string)
        if !ok {
            // this will break iteration
            return false
        }
        // do something with key/value
        fmt.Println(key, val)
    
        // this will continue iterating
        return true
    })
    

    General Advice

    You should test your server with -race option and then eliminate all the race conditions it throws. That way you can easier eliminate such errors before they occur.

    go run -race server.go
    

    See golang race detector

    0 讨论(0)
提交回复
热议问题