QList, QVector or std::vector multi-threaded usage

那年仲夏 提交于 2019-12-10 22:12:22

问题


I would like two threads work like this:

  1. First thread will append values to vector
  2. Second thread will have read-only access to elements by index

I can make mutex and make deep copy before second thread start reading.... But this way is really slow... How is it possible to make this without mutex? Here: STL vector and thread-safety I read that it is possible to use std::deque, but it fails like std::vector ...

Where I can find append-only container, which don't realloc data?


I have solved my problem by creating own container GrowVector with operations: adding elements to back, getting size, accessing element by index. It works for 2Billion elements for default, but it can be changed by constructor parameter.

#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];    
    }
};

Is my solution safe?


回答1:


Your solution is not thread-safe without a locking mechanism.

You can use tbb::concurrent_vector or Concurrency::concurrent_vector for multiple insertion and access simultaneously. No extra locking required. It is unsafe to erase elements from those vectors, but you are ok with it I guess.




回答2:


QList and QVector are re-entrant, so as long as you never the read the last entry whilst thread one is active (so you don't get a value mid-write), and always use at() in the second thread (so no deep copy occurs, this avoids issues with the growth reallocation) you should be OK.

Otherwise you need synchronisation.




回答3:


STL containers does not provide thread safe by default. For concurrent operations on data structures, it is best to provide your own synchronized access to meet thread safe operations.



来源:https://stackoverflow.com/questions/9597101/qlist-qvector-or-stdvector-multi-threaded-usage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!