如何在Golang中实现地图的线程安全地图?

发布于 2025-02-01 11:44:36 字数 574 浏览 2 评论 0原文

我正在研究一个多线程模块,并且需要在Golang中实现MAP的地图 - MAP [ofter] Map [innin]*some_struct。外部键(MAP [OUTAR])将通过多个线程(Goroutines)访问,以将键添加到内映射中。我怀疑是否可以同时将密钥添加到内映射中,以获取一个公共的外键-MAP [outer]。它是安全的,并且同步是一个更好的选择吗? 另外,外部键[外部]和外键总数在运行时已知,因此无法事先定义锁。

为了更好地理解问题陈述,我们可以添加有关不同城市的信息的示例。我们可以按各州对城市进行分组。每个线程代表一个城市。要添加有关城市的信息,第一个线程需要检查外键 - 状态,(映射[state]),然后每个线程只需将信息添加到map [state] [state] [city] =& soly_struct {x:y ,y:z}

我读了很少的文章,发现同步法适合并发地图操作,这些操作是原子进行的。但是在文档中,提到的用例之一是 - 当多个goroutines读取,写入和覆盖键的条目 时。

如果有人可以为此问题陈述建议线程安全方法,将会有所帮助。

I am working on a multi-threaded module and need to implement map of map in golang - map[outer]map[inner]*some_struct. The outer key(map[outer]) will be accessed by multiple threads(goroutines) to add key to inner map. I have a doubt if multiple threads can concurrently add keys to inner map, for a common outer key - map[outer]. Is it thread safe and is sync.Map a better option ?
Also outer key- map[outer] and total number of outer keys are known at runtime so can't define locks beforehand.

To better understand the problem statement, we can take example of add information about different cities. We can group cities by states. Each thread represents a city. To add info about a city, first thread needs to check outer key - state,(map[state]) and then each thread will simply add info to map[state][city] = &some_struct{x:y,y:z}.

I have read few articles and found out sync.Map is suitable for concurrent map operations and these operations are performed atomically. But in documentation one of the use-case mentioned was - when multiple goroutines read, write, and overwrite entries for disjoint sets of keys.

It will be helpful if someone can suggest thread-safe approach for this problem statement.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

束缚m 2025-02-08 11:44:37

您必须用oo术语

来实用该地图的地图?

地图状态,城市有意义。但是,您想做什么样的操作?

写和阅读,并发?为什么?

您想在所有城市上迭代吗?您需要删除城市/州吗?

以下接口

type DB interface {
  Exists(state, city string) bool
  Get(state, city string) *some_struct
  Set(state, city string, data *some_struct)
  Delete(state, city string)
  DeleteState(state string)
  ForeachCitiesInState(state string, func(city string, data *some_struct) bool)
  Foreach(func(state, city…))
}

想象一下我们可以考虑使用此接口的

  1. :使用带有互斥品的结构和地图地图来控制每个读取/写入/删除与1相同的访问,
  2. ,请读取witr witr witr witr witr
  3. 但是如果您读的话 t需要在特定状态下的城市循环,也许
    您可以创建一个地图[复合密钥] struct,例如状态:city to
    简化。
  4. 如果您将其从另一个地方持续的时间间隔加载,也许您应该使用atomic.value存储大地图。更新只是最近地图的替代。
  5. 也许您可以组合几个RW锁。例如,一个用于州,另一个用于城市。您可以像
type states struct {
sync.Mutex
map[ stateName ]state
}

type state struct {
sync.Mutex
map[ cityFirstLetter ]cities
}

type cities struct {
sync.Mutex
map[ cityName ] *some_struct
}

想法那样拆分:

  1. 定义接口
  2. 定义(或测量)用法的真实场景
  3. 写入基准测试
  4. ,请返回数据指针。您可以更改内部状态。考虑返回副本或接口

You must thing in OO terms

What do you want to represent as map of map?

Map state, city make some sense. However what kind of operations do you want to do?

Write and Read, concurrent? Why?

Do you want to iterate over all cities? Do you need to delete cities/states?

Imagine the following interface

type DB interface {
  Exists(state, city string) bool
  Get(state, city string) *some_struct
  Set(state, city string, data *some_struct)
  Delete(state, city string)
  DeleteState(state string)
  ForeachCitiesInState(state string, func(city string, data *some_struct) bool)
  Foreach(func(state, city…))
}

With this interface we can consider:

  1. use a struct with a Mutex and map of maps to control the access on each read/write/delete
  2. same as 1 but with Read Write Mutex if you have more reads than writes
  3. if you don’t need loop over cities on a particular state, perhaps
    you can create a map[ composite key ] struct like state:city to
    simplify.
  4. If you will load it from another place with a constant time interval, perhaps you should use atomic.Value to store the big map. Update is just a substitution for a more recent map.
  5. Perhaps you can combine several rw locks. For instance one for state and another for city. You can split like
type states struct {
sync.Mutex
map[ stateName ]state
}

type state struct {
sync.Mutex
map[ cityFirstLetter ]cities
}

type cities struct {
sync.Mutex
map[ cityName ] *some_struct
}

Ideas:

  1. Define the interface
  2. Define (or measure) the real scenario of usage
  3. Write benchmarks
  4. Be careful by return a pointer to data. You can change the internal state. Consider return a copy or an interface
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文