【问题标题】:Is write-only to a shared std::unordered_map thread safe?只写共享 std::unordered_map 线程安全吗?
【发布时间】:2019-01-31 16:50:40
【问题描述】:

假设我有一个已初始化但为空的 std::unordered_map,以及将填充它的两个同时线程。这两个线程只会写入映射,在两个线程完成之前不会从映射中读取任何内容。

此外,这两个线程永远不会对映射中的相同键进行操作。例如,假设线程 1 将填充键“A”到“M”,线程 2 将同时填充键“N”到“Z”。

这个线程安全吗?

在我当前的实现中,我有 8 个线程以上述方式写入单个互斥的 std::unordered_map。互斥锁显然会减慢进程(填充了近 10,000 个键),所以我想知道我是否还需要互斥锁。

谢谢大家!

【问题讨论】:

  • 我看到了类似的问题。如果性能很重要,请考虑不同的数据结构。如果它们不通过键相交,那么每个线程的 unordered_map 可能是最好的。
  • 阅读 std::unordered_map::merge。两个线程可以填充两个不同的映射,然后一个可以合并它们。
  • @ÖöTiib 这需要 C++17。 Q 被标记为 C++11

标签: c++ c++11 unordered-map


【解决方案1】:

不,它不是线程安全的。 std::unordered_map 类不提供任何特殊的线程安全保证,只是所有标准类默认提供的普通级别的线程安全。这意味着当另一个线程正在或可能正在修改它时,一个线程以任何方式访问该结构都是不安全的。

【讨论】:

  • IRC,对于 std 类有一些关于 const 方法的额外保证,但它们与这种情况无关。它可以破坏的一种简单方法是,如果插入新值会触发重新散列,而其他线程正在插入另一个值。
  • @DanM。所有const 函数都是阅读器,所以如果你正在做这一切就好了。只要您将作家添加到组合中,尽管所有赌注都已关闭
  • @DanM。我不喜欢推测它可能会破坏的方式,因为这会导致(不幸的是,非常普遍的)误解,即如果您想不出一种可以破坏的方式并且当您尝试它时它碰巧起作用,那么它是安全的做。
  • @DanM。这是一个人如何被误导的完美例子。您可以想到一种可能失败的方法是不是为什么他的非常具体的用例不是线程安全的。他非常具体的用例不是线程安全的,因为相关标准是这样说的。即使没有人能想到失败的方法也不是线程安全的。不幸的是,这是一个非常普遍的误解,多年来导致了巨大的痛苦和痛苦。
  • 这就是为什么我想问而不是本地测试...不确定我的简单测试是否会 A) 一致工作并且 B) 可以扩展到我的完整实现。鉴于所有这些信息,我将只保留互斥锁。谢谢大家!
猜你喜欢
  • 2013-07-08
  • 1970-01-01
  • 2012-03-29
  • 2017-12-23
  • 2017-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多