Lock the map for concurrent access to the map

WBOY
Release: 2024-02-09 11:06:09
forward
1085 people have browsed it

Lock the map for concurrent access to the map

php editor Baicao is here to introduce to you a very useful technique, which is to lock the map for concurrent access. This technique can help developers avoid conflicts and data errors when accessing the map concurrently. By using a locking mechanism, developers can ensure that each request is made in order and that no data clutter occurs. This is very important for developing map operations, especially when multiple users are accessing the map at the same time. Let’s take a look at how to implement this technique!

Question content

I have a map: map[string]map[string]*Struct and I need to read/write it in multiple Go routines.

What is the best way to achieve this? Mutex or RWMutex? And where to place it?

If I use RWMutex, should I Lock or RLock before performing operations involving reading and writing?

I tried using rwmutex in the root map, but I'm not sure if that's the best way to solve this problem.

I also tried "locking" before reading and writing, but sometimes I get "concurrent writes" panics.

Solution

You can use RWLock. If the operation involves writing (whether it is reading or writing only), you need to use Lock, if it only involves reading, RLock/RUnlock.

Lock can also be considered an exclusive lock. RLock, on the other hand, is non-exclusive. An RLock can be acquired even if the RWMutex is locked for reading, but goroutine execution will be blocked if the resource is locked exclusively by the Lock method:

a blocked Lock call excludes new readers from acquiring the lock
Copy after login

On the other hand, the Lock method blocks goroutine execution until all readers and writers unlock the resource (using the RUnlock/Unlock method). Lock is exclusive because only one goroutine can access the resource (whether reading or writing) until the Unlock method is called.

Typical method:

package main

import (
    "fmt"
    "sync"
)

type SomeStruct struct {
    someInfo string
}

type ConcurrentStruct struct {
    mu   sync.RWMutex
    data map[string]map[string]*SomeStruct
}

func New() *ConcurrentStruct {
    return &ConcurrentStruct{
        data: make(map[string]map[string]*SomeStruct),
    }
}

func (cs *ConcurrentStruct) Set(key1, key2 string, val SomeStruct) {
    cs.mu.Lock()
    defer cs.mu.Unlock()

    if _, ok := cs.data[key1]; !ok {
        cs.data[key1] = make(map[string]*SomeStruct)
    }
    cs.data[key1][key2] = &val
}

func (cs *ConcurrentStruct) Get(key1, key2 string) (val *SomeStruct, ok bool) {
    cs.mu.RLock()
    defer cs.mu.RUnlock()

    if _, ok := cs.data[key1]; ok {
        val, ok := cs.data[key1][key2]
        return val, ok
    }

    return nil, false
}

func main() {
    cs := New()
    cs.Set("a", "b", SomeStruct{"Hello, World!"})

    if _, ok := cs.Get("a", "c"); !ok {
        fmt.Printf("key1=a, key2=c, not found\n")
    }

    if s, ok := cs.Get("a", "b"); ok {
        fmt.Printf("key1=a, key2=b, found: %v\n", s)
    }
}
Copy after login

The above is the detailed content of Lock the map for concurrent access to the map. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template