有谁知道我在哪里可以找到包裹std::map
并使其线程安全的瑕疵?当我说线程安全时,我的意思是它只提供对地图的串行访问,一次一个线程。最理想的是,此映射应仅使用标准库和/或boost构造。
答案 0 :(得分:11)
不符合您指定的条件,但您可以查看TBB容器。有一个所谓的concurrent_hash_map
,允许多个线程同时访问地图中的数据。有一些细节,但一切都很好地记录,可以让你了解“并发容器”。根据您的需要,这可能完全不合适......
答案 1 :(得分:4)
集合类提供线程安全通常不是一个好主意,因为他们无法知道如何使用它们。通过在使用集合的更高级别构造中实现自己的锁定机制,您将获得更好的服务。
答案 2 :(得分:2)
在给定约束的情况下,boost shared_mutex将提供最佳的多读取器/单写入器方法来包装标准映射。我不知道任何与这两者结合的“预建”实现,因为这项任务通常是微不足道的。
答案 3 :(得分:1)
这取决于要实施的应用程序。 “线程安全”映射会使对映射的单独调用成为线程安全的,但许多操作需要在调用之间进行线程安全。使用映射的应用程序应将互斥锁与地图关联,并使用该互斥锁来协调对它的访问。
尝试制作线程安全的容器在Java中是一个错误,在C ++中会出错。
答案 4 :(得分:1)
试试这个库
http://www.codeproject.com/KB/threads/lwsync.aspx
它是在现代基于c ++策略的方法中实现的。
以下是链接中的一些内容,用“向量”案例
显示这个想法typedef lwsync::critical_resource<std::vector<int> > sync_vector_t;
sync_vector_t vec;
// some thread:
{
// Critical resource can be naturally used with STL containers.
sync_vector_t::const_accessor vec_access = vec.const_access();
for(std::vector<int>::const_iterator where = vec_access->begin();
where != vec_access->end();
++where;
)
std::cout << *where << std::endl;
}
sync_vector_t::accessor some_vector_action()
{
sync_vector_t::accessor vec_access = vec.access();
vec_access->push_back(10);
return vec_access;
// Access is escalated from within a some_vector_action() scope
// So that one can make some other action with vector before it becomes
// unlocked.
}
{
sync_vector_t::accessor vec_access = some_vector_action();
vec_access->push_back(20);
// Elements 10 and 20 will be placed in vector sequentially.
// Any other action with vector cannot be processed between those two
// push_back's.
}
答案 5 :(得分:1)
答案 6 :(得分:0)
我想出了这个(我确信可以改进以获得两个以上的论点):
template<class T1, class T2>
class combine : public T1, public T2
{
public:
/// We always need a virtual destructor.
virtual ~combine() { }
};
这允许你这样做:
// Combine an std::mutex and std::map<std::string, std::string> into
// a single instance.
combine<std::mutex, std::map<std::string, std::string>> lockableMap;
// Lock the map within scope to modify the map in a thread-safe way.
{
// Lock the map.
std::lock_guard<std::mutex> locked(lockableMap);
// Modify the map.
lockableMap["Person 1"] = "Jack";
lockableMap["Person 2"] = "Jill";
}
如果你想使用std :: recursive_mutex和std :: set,那也可以。
答案 7 :(得分:0)
这里有一个命题(对我来说,是无耻的插件),它包装了对象(包括STL
个容器)以实现高效(零成本)线程安全访问:
https://github.com/isocpp/CppCoreGuidelines/issues/924
基本思想很简单。仅有少量包装器类用于强制执行读/写锁定,同时提供包装对象的const(只读)或非const(读写)视图。
该想法是使编译时无法正确访问线程之间共享的资源。
实施代码可以在这里找到:
https://github.com/galik/GSL/blob/lockable-objects/include/gsl/gsl_lockable