我正在寻找一个由2个作者和多个读者组成的简单结构的地图。为了使其具有线程安全性,我目前正在使用具有唯一锁的互斥锁(下面的代码)。在结构上将只有插入和编辑操作,而不会擦除。
但是,由于写操作比读操作要频繁得多(大约1m的写操作与同一时间的15-20,000个读操作),我担心使用唯一锁会影响读的性能操作。
我想知道是否有更好/更简单的方法来为我的问题实现简单的并发映射?例如,每次执行写/读操作时,仅锁定结构本身而不是锁定整个映射会更好吗?
我研究了Intel TBB并发无序映射和Pershing的Junction映射,但是如果可能的话,我宁愿坚持使用STL。
我正在使用C ++ 11,因此shared_lock不可用。我打算对读取操作使用boost :: shared_lock,但是从this post中我了解到,锁定shared_mutex的成本比普通的要高。
编辑:在评论中编辑了代码发布讨论。
#include <mutex>
struct Foo
{
double bar1 = 0;
long bar2 = 0;
};
typedef std::shared_ptr<Foo> FooPtr;
class FooMap
{
std::mutex mMutex;
std::unordered_map<long, FooPtr> mMap;
public:
FooPtr get(long const& key)
{
return mMap[key];
}
void set(long const& key, double a, long b)
{
std::unique_lock<std::mutex> lock(mMutex);
mMap[key]->bar1 = a;
mMap[key]->bar2 = b;
}
};
答案 0 :(得分:1)
好吧,我放弃...恐怕您的代码与我的想法相去甚远。这是我真正的建议,您在其中写入共享库的新实例以创建新的foo:
#include <mutex>
struct Foo
{
double bar1 = 0;
long bar2 = 0;
};
typedef std::shared_ptr<Foo> FooPtr;
typedef std::shared_ptr<const Foo> CFooPtr;
class FooMap
{
std::mutex mMutex;
std::unordered_map<long, FooPtr> mMap;
public:
CFooPtr get(long const& key)
{
auto found = mMap.find(key);
if (found == mMap.end())
{
return nullptr;
}
return found->second;
}
void set(long const& key, double a, long b)
{
FooPtr tmp = make_shared<Foo>({a,b});
{
std::unique_lock<std::mutex> lock(mMutex);
mMap[key].swap(tmp);
}
// previous entry contents are destroyed outside mutex
}
};
答案 1 :(得分:0)
在这里,您只能在以下位置找到带有STL的无锁哈希映射的设计: https://shlomisteinberg.com/2015/09/28/designing-a-lock-free-wait-free-hash-map/
要求在大量写入时要优于TBB。