[英]How to use `std::unordered_map` in a thread-safe way?
我的想法是包装std::unordered_map
,并为每个操作锁定它。 它看起来像这样(我将只留下一个操作,以免混淆问题):
template<class Key, class T>
class thread_safe_unordered_map {
public:
T &operator[](const Key &key) {
std::lock_guard<std::mutex> lock{m_mutex};
return m_underlying[key];
}
private:
std::unordered_map<Key, T> m_underlying;
std::mutex m_mutex;
};
但是后来我想到了这一点,现在我不知道如何正确地做到这一点。
想象一下这种情况。
线程1:调用operator[]写
线程 2:调用 operator[] 从中读取
两者都做自己的事情。 现在,因为 operator[] 返回一个引用,并且它们都将作用于同一个引用,我认为这仍然可能是数据竞争。 这是正确的吗?
因为这个:
所有 const 成员函数都可以被同一容器上的不同线程并发调用。 另外,成员函数begin()、end()、rbegin()、rend()、front()、back()、data()、find()、lower_bound()、upper_bound()、equal_range()、 at(),并且,除了在关联容器中,operator[] 出于线程安全的目的表现为 const。
我有这个问题。 在线程上使用at()
是否正确,并且被锁定的是映射值?
现在,因为 operator[] 返回一个引用,并且它们都将作用于同一个引用,我认为这仍然可能是数据竞争。 这是正确的吗?
假设T
不是线程安全类型,这是正确的。
这不是容器操作中的数据竞争,而是使用类型T
的对象中的数据竞争。
我有这个问题。 在线程上使用 at() 是否正确
如果您只调用限定at
的常量,那么您永远不会获得非常量引用,因此无法修改任何元素的值。 如果您不修改这些值,则不会发生数据竞争。
如果您使用限定at
,则在描述的数据竞争方面没有区别。
PS 你会发现你不能有任何同步的非常量成员函数,因为锁定互斥体需要修改。 你可以使用mutable
来解决这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.