【问题标题】:Thread safe C++ std::set that supports add, remove and iterators from multple threads线程安全的 C++ std::set 支持从多个线程添加、删除和迭代器
【发布时间】:2009-09-10 11:22:15
【问题描述】:

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

【问题讨论】:

    标签: c++ multithreading thread-safety set std


    【解决方案1】:

    据我所知没有一个,最接近的是线程构建块,它有concurrent_unordered_map

    只要您不进行并发修改,STL 容器就允许concurrent read access from multiple threads。通常在添加/删除时不需要迭代。

    关于提供简单包装类的指导是明智的,我将从下面的代码 sn-p 开始,保护您真正需要并发访问的方法,然后提供对基本 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);
        }
    };
    

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            【解决方案5】:

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

            【讨论】:

            • 我认为您不应该从标准容器派生。他们没有虚拟析构函数。在这种情况下,组合会更好。
            【解决方案6】:

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

            【讨论】:

              【解决方案7】:

              线程安全和写时复制语义不是一回事。话说……

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

              【讨论】:

                猜你喜欢
                • 2010-11-24
                • 2018-04-07
                • 1970-01-01
                • 1970-01-01
                • 2012-03-07
                • 2012-03-19
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多