我希望两个线程像这样工作:
我可以在第二个线程开始读取之前制作互斥并进行深度复制....但这种方式真的很慢......如何在没有互斥的情况下制作它?在这里:STL vector and thread-safety 我读过可以使用std :: deque,但它失败了,就像std :: vector ...
哪里可以找到仅附加容器,哪些不重新分配数据?
我通过创建自己的容器GrowVector来解决我的问题:操作:向后添加元素,获取大小,按索引访问元素。它适用于默认的2亿个元素,但可以通过构造函数参数进行更改。
#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];
}
};
我的解决方案安全吗?
答案 0 :(得分:3)
QList
和QVector
是可重入的,所以只要您从未读过最后一个条目,而第一个线程处于活动状态(因此您不会在写入中间获得值),并且总是在第二个线程中使用at()
(因此不会发生深层复制,这可以避免增长重新分配的问题)你应该没问题。
否则你需要同步。
答案 1 :(得分:2)
默认情况下,STL容器不提供线程安全。对于数据结构的并发操作,最好提供自己的同步访问以满足线程安全操作。
答案 2 :(得分:1)
如果没有锁定机制,您的解决方案就不是线程安全的。
您可以同时使用tbb::concurrent_vector或Concurrency::concurrent_vector进行多次插入和访问。无需额外锁定。从这些矢量中删除元素是不安全的,但我猜你也没问题。