繁体   English   中英

C ++线程安全映射

[英]C++ Thread-Safe Map

有谁知道我在哪里可以找到包装std::map并使其成为线程安全的隐含内容? 当我说线程安全时,我的意思是说它仅提供对映射的串行访问,一次仅提供一个线程。 最佳情况下,此映射应仅使用标准库和/或boost结构。

不符合您指定的条件,但是您可以看一下TBB容器。 有所谓的concurrent_hash_map ,它允许多个线程访问同时在地图数据。 有一些细节,但是所有内容都有很好的记录,可以使您对“并发容器”有所了解。 根据您的需求,这可能是完全不合适的...

收集类提供线程安全性通常不是一个好主意,因为它们不知道如何使用它们。 通过在使用集合的更高级别构造中实现自己的锁定机制,可以为您提供更好的服务。

在您的约束下,boost shared_mutex将提供最佳的多重读取器/单个写入器方法来包装标准地图。 我不知道将这两种方法结合使用的任何“预构建”实现,因为任务通常很简单。

您可能会看到线程安全模板库

这取决于应用程序要实现。 “线程安全”映射将使各个调用成为线程安全的映射,但是许多操作需要调用之间变为线程安全。 使用该映射的应用程序应将一个互斥锁与该映射相关联,并使用该互斥锁来协调对其的访问。

尝试制作线程安全的容器在Java中是一个错误,而在C ++中则是一个错误。

试试这个图书馆

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.
}

我想出了这一点(我敢肯定,可以接受两个以上的论点进行改进):

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,那也可以。

这里有一个命题(对我来说,是无耻的插件),它包装对象(包括STL容器)以进行有效的(零成本)线程安全访问:

https://github.com/isocpp/CppCoreGuidelines/issues/924

基本思想很简单。 只有少数包装器类用于强制执行读/写锁定,同时提供包装对象的const(只读)或非const(读写)视图。

这样做的想法是使编译时无法正确访问线程之间共享的资源。

实现代码可以在这里找到:

https://github.com/galik/GSL/blob/lockable-objects/include/gsl/gsl_lockable

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM