2

我正在寻找类似于 Java 中的 CopyOnWriteSet 的东西,一个支持 的集合addremove以及iterators来自多个线程的某种类型。

4

7 回答 7

5

我不知道,最接近的是线程构建块,它有concurrent_unordered_map

只要您不进行并发修改,STL 容器就允许从多个线程进行并发读取访问。通常在添加/删除时不需要迭代。

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

我在并行模式库上工作,所以我使用 VS2010 beta boost::mutex 中的 critical_section 也很有效,而且无论您如何选择执行此操作,几乎都需要使用 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);
    }
};
于 2009-09-11T19:50:47.613 回答
3

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

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

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

我一直认为并发和集合行为是正交的概念,所以最好将它们放在单独的类中。以我的经验,试图自己线程安全的类不是很灵活或没有那么有用。

于 2009-09-10T17:31:13.693 回答
1

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

于 2009-09-10T11:54:47.117 回答
1

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

于 2009-09-23T15:26:52.960 回答
0

我能想到的就是使用 OpenMP 进行并行化,从 std 派生一个集合类,并在每个关键集合操作周围放置一个外壳,使用 #pragma omp critical 声明该操作是关键的。

于 2009-09-10T11:26:08.043 回答
0

Qt的QSet类使用隐式共享(copy on write语义)和std::set类似的方法,可以看它的实现,Qt是lgpl。

于 2009-09-10T11:42:11.793 回答
0

线程安全和写时复制语义不是一回事。话虽如此...

如果您真的很喜欢写时复制语义,Adobe 源库有一个copy_on_write模板,可以将这些语义添加到您使用的任何实例中。

于 2009-09-10T17:38:05.410 回答