2009-09-10 458 views

回答

4

没有一个是我知道的,最接近的是其中有concurrent_unordered_map

的STL容器允许concurrent read access from multiple threads只要你不没有做并发修改线程构建模块。通常在添加/删除时不需要重复。

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

我对并行模式库工作,所以我使用CRITICAL_SECTION从VS2010测试版的boost ::互斥的伟大工程太也不管你选择如何做到这一点使用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); 
    } 
}; 
0

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

+0

我不认为你应该从std容器派生。他们没有虚拟析构函数。在这种情况下,构图会更好。 – 2009-09-10 13:29:41

0

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

1

你也可以看看ACE库,它有你可能需要的所有线程安全容器。

3

为什么不只是使用共享互斥体来保护并发访问?一定要使用RAII锁定和解锁互斥:

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

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

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

0

线程安全性和写入语义上的拷贝不是一回事。这就是说...

如果你真的在写时复制语义之后,Adobe Source Libraries有一个copy_on_write模板,它将这些语义添加到任何实例化它的任何东西。

1

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