【发布时间】:2012-03-24 17:20:23
【问题描述】:
我希望两个线程像这样工作:
- 第一个线程将值附加到向量
- 第二个线程将通过索引对元素进行只读访问
我可以在第二个线程开始读取之前制作互斥体并进行深层复制......但是这种方式真的很慢......没有互斥体怎么可能做到这一点?这里: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