我正在寻找类似于Java中的CopyOnWriteSet的东西,这个集合支持 add remove 和某些类型的 iterators 多线程。

有帮助吗?

解决方案

没有我所知道的,最接近的是具有 concurrent_unordered_map

的线程构建块

STL容器允许来自多个线程的并发读取访问权限只要你不做并发修改。通常没有必要在添加/删除时进行迭代。

关于提供简单包装类的指导是理智的,我会从下面的代码片段开始,保护你真正需要并发访问的方法,然后提供对基本std :: set的“不安全”访问权限可以选择其他不安全的方法。如果有必要,你可以保护访问以及获取迭代器并将它们放回去,但这很棘手(仍然不如编写自己的锁定集或你自己的完全同步集)。

我在并行模式库上工作,所以我正在使用VS2010 beta的训练版:: mutex也很有效,无论你如何选择这样做,使用lock_guard的RAII模式几乎是必要的:

template <class T>
class synchronized_set
{
    //boost::mutex is good here too
    critical_section cs;
public:
    typedef set<T> std_set_type;
    set<T> unsafe_set;
    bool try_insert(...)
    {
        //boost has a lock_guard
        lock_guard<critical_section> guard(cs);
    }
};

其他提示

为什么不使用共享互斥锁来保护并发访问?务必使用RAII来锁定和解锁互斥锁:

{
   Mutex::Lock lock(mutex);
   // std::set manipulation goes here
}

其中Mutex :: Lock是一个锁定构造函数中的互斥锁并在析构函数中解锁它的类,而互斥锁是一个由所有线程共享的互斥锁对象。 Mutex只是一个包装类,它隐藏了您正在使用的任何特定操作系统原语。

我一直认为并发和集合行为是正交概念,因此最好将它们放在不同的类中。根据我的经验,尝试线程安全的类本身并不是非常灵活或者非常有用。

您不希望内部锁定,因为您的不变量通常需要对数据结构进行多次操作,而内部锁定只能防止步骤同时发生,而您需要保留不同宏操作的步骤交织。

您还可以查看ACE库,其中包含您可能需要的所有线程安全容器。

我能想到的是使用OpenMP进行并行化,从std中派生一个set类,并在每个批判集操作周围放置一个shell,该操作使用#pragma omp critical来声明该操作至关重要。

Qt的QSet类使用隐式共享(写入语义上的复制)和类似的方法与std :: set,你可以看看它的实现,Qt是lgpl。

线程安全和写入语义上的复制不是一回事。那就是说......

如果你真的在写时复制语义之后,Adobe源库有一个 copy_on_write 模板,将这些语义添加到您使用它实例化的任何内容中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top