簡體   English   中英

QList,QVector或std :: vector多線程用法

[英]QList, QVector or std::vector multi-threaded usage

我想兩個線程是這樣的:

  1. 第一個線程將值附加到向量
  2. 第二個線程將按索引對元素進行只讀訪問

我可以制作互斥鎖並在第二個線程開始讀取之前進行深層復制。...但是這種方式確實很慢...在沒有互斥鎖的情況下如何做到這一點? 在這里: STL向量和線程安全性我讀到可以使用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];    
    }
};

我的解決方案安全嗎?

QListQVector是可重入的,因此只要您在一個線程處於活動狀態時從不讀取最后一個條目(這樣就不會在寫入過程中得到值),並且始終在第二個線程中使用at()沒有深度復制發生,這避免了增長重新分配的問題),您應該可以。

否則,您需要同步。

STL容器默認情況下不提供線程安全。 對於數據結構上的並發操作,最好提供自己的同步訪問權限,以滿足線程安全的操作。

沒有鎖定機制,您的解決方案就不是線程安全的。

您可以使用tbb :: concurrent_vectorConcurrency :: concurrent_vector進行多次插入和同時訪問。 無需額外的鎖定。 從這些向量中刪除元素是不安全的,但是我猜你對此很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM