C++ 线程安全映射

发布于 2024-07-18 11:01:32 字数 122 浏览 9 评论 0原文

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

Does anyone know where I can find an implimentation that wraps a std::map and 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

夏尔 2024-07-25 11:01:32

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

Does not meet the criteria that you have specified, but you could have a look at the TBB containers. There is so called concurrent_hash_map which 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...

安人多梦 2024-07-25 11:01:32

考虑到您的限制,boost Shared_mutex 将提供最佳的多读取器/单写入器方法来包装标准映射。 我不知道有任何将这两者结合起来的“预构建”实现,因为任务通常很简单。

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.

暗地喜欢 2024-07-25 11:01:32

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

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

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

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

魔法唧唧 2024-07-25 11:01:32

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

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.

魔法少女 2024-07-25 11:01:32

尝试这个库

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

Try this library

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

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

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.
}
魔法少女 2024-07-25 11:01:32

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

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

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

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

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

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

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

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

又爬满兰若 2024-07-25 11:01:32

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

尝试创建线程安全的容器在 Java 中是一个错误,在 C++ 中也是一个错误。

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 across calls. 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++.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文