【问题标题】:Does TBB concurrent vector support old c style loops?TBB 并发向量是否支持旧的 c 样式循环?
【发布时间】:2015-09-25 13:18:15
【问题描述】:
所以tbb vector 允许获取开始指针和长度(大小)。那么我们可以安全地假设我们可以在不加锁的情况下从开始到开始+长度进行迭代吗?或者我们如何将指针内容传递给接受开始指针和长度的 C 风格函数?我们是否应该只在从向量中删除元素时提供锁定并且并发增长是可以接受的?
现实生活中的问题:指向 zmqsockets 的指针的并发向量同时变得越来越小。一个带有 zmq poll 的线程,提供 C 风格的迭代。
【问题讨论】:
标签:
c++
c
vector
concurrency
tbb
【解决方案1】:
tbb::concurrent_vector<> 不代表用于存储其元素的连续数组/内存区域。请注意文档中的Fragmentation部分:
与 std::vector 不同,concurrent_vector 在增长时从不移动现有元素。容器分配一系列连续的数组。 ...
这个blog可视化了concurrent_vector的结构,如果你考虑到内存段是单独分配的并且在内存中可以有不连续的地址:
所以,回答
我们如何将指针内容传递给接受开始指针和长度的 C 风格函数
是你不能这样做,因为不能保证所有元素的连续内存(除非你决定单独处理每个段)。
您可以使用迭代器或[] 运算符来遍历 concurrent_vector,这看起来与 C 样式的循环完全一样:
for(i = 0; i < conc_vec.size(); i++)
printf(" %d", conc_vec[i])
但是在存在同时增长向量的其他线程的情况下,只有当您知道所有元素都已构建的向量的安全大小时,它才是安全的。按照该博客的建议,可以通过额外的努力并使用tbb::zero_allocator 来避免锁定。