c++ - 多个线程在 C++ 中访问 std::map

标签 c++ multithreading hashmap

我正在写一个 Minecraft 的克隆版本,我真的想为世界生成、更新 block 、光传播等实现多线程。 我将所有加载的 block 存储在 HashMap “chunk_map”中。

在 chunk_map 上放置互斥锁会破坏多线程的全部目的,因为每个线程的大部分工作都在 chunk_map 上迭代。

如果我的想法是正确的,那么在 map 中插入一个新 block 应该不是问题(在最坏的情况下,线程可能会跳过刚刚添加的 block ) 但是删除一个chunk肯定是个问题。

使用 shared_ptr 而不是 iterator_type 的散列映射实现是否可以解决从映射中删除 am 元素而其他线程遍历该映射的问题? 还是有一些不同的、更简单的方法?

编辑: 我想完全避免同步线程,因为我不希望世界生成、 block 更新等限制渲染性能。

我希望主线程渲染当前加载的所有 block 。 我还希望“更新程序线程”更新每个加载 block 中的每个 block ,等等。 以及加载和卸载 block 的“世界线程”。

最佳答案

不幸的是,你的问题是基于一个错误的前提:

If what i'm thinking is correct, inserting a new chunk into the map shouldn't be problem (in the worst case scenario a thread might skip a chunk that has just been added) But deleting a chunk would definitely be a problem.

不,你错了。最坏的情况比这更糟。考虑:

  1. 线程 A 构造一个新 block 。
  2. 线程 A 将该 block 添加到映射中。
  3. 线程 B 在映射中看到新 block 的条目。
  4. 线程 B 尝试访问该 block ,但由于代码优化和重新排序写入的硬件,它看不到线程 A 在步骤 1 中进行的写入。

糟糕,你的程序刚刚崩溃了。

你推理中的关键缺陷,这是一个非常常见的缺陷,如果你想成为一名成功的程序员,你绝对必须在推理中修正它,它认为如果你违反明确的规则,唯一可能出错的地方是你可以预见的事情。这种推理在计算机编程领域是绝对的死亡。

所以,事实上,绝对最坏的情况比我上面说的还要糟糕。您违反了您正在使用的类的要求,该类的实现会因平台而异。您绝对无法知道哪里会出错。

关于c++ - 多个线程在 C++ 中访问 std::map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57205647/

相关文章:

arrays - Ruby: "upserting"散列中数组值的更惯用方式

integer - Json String包含整型值,反序列化为HashMap,Integer转为double值

c++ - 根据 vector 大小删除 for 循环内 std::vector 的索引

c++ - "Attempting to reference a deleted function"

c - 银行家算法线程创建未完全运行传递的方法

multithreading - 在具有多个用户的网络上使用 MSMQ 与在本地使用一个用户

c# - 当多个线程生成的进程将文件复制到同一目录 C# 时缺少文件条目

c++在范围末尾出现双重释放或损坏错误

c++ - 是否有一个库类来表示 float ?

java - 每当发现重复键时如何创建新的 HashMap?