【问题标题】:QList, QVector or std::vector multi-threaded usageQList、QVector 或 std::vector 多线程使用
【发布时间】:2012-03-24 17:20:23
【问题描述】:

我希望两个线程像这样工作:

  1. 第一个线程将值附加到向量
  2. 第二个线程将通过索引对元素进行只读访问

我可以在第二个线程开始读取之前制作互斥体并进行深层复制......但是这种方式真的很慢......没有互斥体怎么可能做到这一点?这里:STL vector and thread-safety 我读到可以使用std::deque,但它像std::vector一样失败......

在哪里可以找到不重新分配数据的仅附加容器?


我通过使用以下操作创建自己的容器 GrowVector 解决了我的问题:将元素添加到后面、获取大小、按索引访问元素。它默认适用于 20 亿个元素,但可以通过构造函数参数进行更改。

#include <vector>

template<typename T>
class GrowVector
{
    std::vector<std::vector<T> > m_data;
    size_t m_size;

public:
    GrowVector(int chunks = 32768)
        : m_data()
        , m_size(0)
    {
        m_data.reserve(chunks);
        m_data.push_back(std::vector<T>());
        m_data.back().reserve(1 << 16);
    }

    void add(const T & value)
    {
        if (m_data.back().size() == m_data.back().capacity())
        {
            m_data.push_back(std::vector<T>());
            m_data.back().reserve(1 << 16);
        }

        m_data.back().push_back(value);
        m_size++;
    }

    size_t size() const
    {
        return m_size;
    }

    T & operator [] (int i)
    {
        return m_data[i >> 16][i & 0xffff]; 
    }

    const T & operator [] (int i) const
    {
        return m_data[i >> 16][i & 0xffff];    
    }
};

我的解决方案安全吗?

【问题讨论】:

  • 如果您从多个线程使用标准库容器并且至少有一个线程正在修改容器,您必须同步对容器的访问。所有标准库容器都是这种情况,而不仅仅是vector
  • 不重新分配内存的唯一方法是如果您已经知道向量中的最大条目数,然后使用reserve。或者 std::array 如果您在编译时已经知道大小。也许您想要 std::list 代替?

标签: c++ multithreading qt thread-safety containers


【解决方案1】:

QListQVector 是可重入的,因此只要您在线程一个处于活动状态时从不读取最后一个条目(因此您不会在写入过程中获得值),并且始终使用 @987654323 @ 在第二个线程中(所以不会发生深拷贝,这避免了增长重新分配的问题)你应该没问题。

否则你需要同步。

【讨论】:

    【解决方案2】:

    默认情况下,STL 容器不提供线程安全。对于数据结构的并发操作,最好提供自己的同步访问来满足线程安全操作。

    【讨论】:

      【解决方案3】:

      如果没有锁定机制,您的解决方案就不是线程安全的。

      您可以使用tbb::concurrent_vectorConcurrency::concurrent_vector 同时进行多次插入和访问。不需要额外的锁定。从这些向量中删除元素是不安全的,但我猜你可以接受。

      【讨论】:

      • 谢谢。 TBB 的 concurrent_vector 看起来像我需要的。
      猜你喜欢
      • 2011-09-29
      • 1970-01-01
      • 2012-02-20
      • 2012-03-07
      • 2011-08-03
      • 2013-11-03
      • 2012-12-12
      • 2018-07-06
      相关资源
      最近更新 更多