C++ 线程安全映射

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/820526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:25:49  来源:igfitidea点击:

C++ Thread-Safe Map

c++dictionarycollectionsthread-safetystdmap

提问by Chris Andrews

Does anyone know where I can find an implimentation that wraps a std::mapand makes it thread safe? When I say thread safe I mean that it offers only serial access to the map, one thread at a time. Optimally, this map should use only the standard-library and / or boost constructs.

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

采纳答案by Anonymous

Does not meet the criteria that you have specified, but you could have a look at the TBBcontainers. There is so called concurrent_hash_mapwhich allows multiple threads to access concurrently the data in the map. There are some details, but everything is nicely documented and can give you an idea of the "concurrent container". Depending on your needs this might be totally inappropriate...

不符合您指定的标准,但您可以查看TBB容器。所谓concurrent_hash_map允许多个线程同时访问映射中的数据。有一些细节,但一切都很好地记录在案,可以让您了解“并发容器”。根据您的需要,这可能完全不合适......

回答by Anonymous

It is generally not a good idea for collection classes to provide thread-safety, because they cannot know how they are being used. You will be much better served by implementing your own locking mechainisms in the higher level constructs that use the collections.

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

回答by Mykola Golubyev

Try this library

试试这个库

http://www.codeproject.com/KB/threads/lwsync.aspx

http://www.codeproject.com/KB/threads/lwsync.aspx

It is implemented in a modern c++ policy based approach.

它以基于现代 C++ 策略的方法实现。

Here is some cut from the link to show the idea with the 'vector' case

这是从链接中截取的一些内容,以展示“矢量”案例的想法

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

回答by Joe

The boost shared_mutex would provide the best multiple reader/single writer approach to wrapping a standard map given your constraints. I don't know of any "pre-built" implementations that marry these two since the task is generally trivial.

boost shared_mutex 将提供最佳的多读取器/单写入器方法来包装标准映射给定您的约束。我不知道将这两者结合在一起的任何“预构建”实现,因为任务通常是微不足道的。

回答by Jay

You might look at Thread Safe Template Library

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

回答by Jerry

I came up with this (which I'm sure can be improved to take more than two arguments):

我想出了这个(我确信可以改进以接受两个以上的论点):

template<class T1, class T2>
class combine : public T1, public T2
{
public:

    /// We always need a virtual destructor.
    virtual ~combine() { }
};

This allows you to do:

这允许您执行以下操作:

// 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"] = "Hyman";
    lockableMap["Person 2"] = "Jill";
}

If you wish to use an std::recursive_mutex and an std::set, that would also work.

如果您希望使用 std::recursive_mutex 和 std::set,那也可以。

回答by Galik

There is a proposition here (by me - shameless plug) that wraps objects (including STLcontainers) for efficient (zero-cost) thread safe access:

这里有一个提议(由我 - 无耻的插件)包装对象(包括STL容器)以实现高效(零成本)线程安全访问:

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

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

The basic idea is very simple. There are just a few wrapper classes used to enforce read/write locking and, at the same time, presenting either a const (for read-only) or non-const (for read-write) view of the wrapped object.

The idea is to make it compile-time impossible to improperly access a resource shared between threads.

基本思想非常简单。只有几个包装类用于强制读/写锁定,同时呈现包装对象的常量(只读)或非常量(读写)视图。

这个想法是使编译时不可能不正确地访问线程之间共享的资源。

Implementation code can be found here:

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

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

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

回答by Dan Breslau

This is up to the application to implement. A "thread-safe" map would make individual calls into the map thread-safe, but many operations need to be made thread-safe acrosscalls. The application that uses the map should associate a mutex with the map, and use that mutex to coordinate accesses to it.

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

Trying to make thread-safe containers was a mistake in Java, and it would be a mistake in C++.

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