QList、QVector或std::vector多线程使用
QList, QVector or std::vector multi-threaded usage
我希望两个线程像这样工作:
- 第一个线程将把值附加到向量
- 第二个线程将按索引对元素进行只读访问
我可以在第二个线程开始读取之前创建互斥并进行深度复制。。。。但这种方式真的很慢。。。没有互斥体怎么可能做到这一点?这里:STL矢量和线程安全我读到可以使用std::deque,但它像std::vector一样失败。。。
在哪里我可以找到只追加的容器,而不是realloc数据?
我已经通过创建自己的容器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];
}
};
我的解决方案安全吗?
QList
和QVector
是可重入的,所以只要在线程一处于活动状态时从不读取最后一个条目(这样在写入过程中就不会得到值),并且总是在第二个线程中使用at()
(这样就不会发生深度复制,这样就避免了增长重新分配的问题),那么应该是可以的
否则,您需要同步。
STL容器默认情况下不提供线程安全。对于数据结构上的并发操作,最好提供自己的同步访问,以满足线程安全操作的要求。
如果没有锁定机制,您的解决方案就不是线程安全的。
您可以使用tbb::concurrent_vector或concurrent::concurrent_vector同时进行多个插入和访问。无需额外锁定。从这些向量中删除元素是不安全的,但我想你可以接受。
相关文章:
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 如何阻止TensorFlow的多线程
- 使用 vector<thread> 和 .join() 未并行运行的多线程C++程序
- QList、QVector或std::vector多线程使用
- 可以用C++std::vector同时处理来自多线程的push_back
- std::vector::erase() (多线程) '断言 'px != 0' 失败。
- c++中带有std::Vector的多线程
- c++使用' .reserve() '填充' std::vector '作为防止多线程缓存无效和错误共享的一种方
- 在多线程C++程序中使用std::vector时导致应用程序崩溃
- 多线程程序,它将线程保存在vector而不是数组中
- 多线程安全地插入vector的最快方法是什么?
- vector多线程同步,一个读一个写:只在调整大小时锁定