C++ | 多线程使用vector

多线程使用vector

场景描述

最近在看代码优化,看到有这样的代码:

std::vector<int> valid_indices;

void SimbaSegmenter::GridFilter::Clean() {
  valid_indices.reserve(rows * cols);
  valid_indices.clear();
}

第一反应是,既然是Clean函数,肯定就是想清空这个数组,清空之前还要reserve一下,不是多此一举吗?

于是将第4行代码去掉了。

程序会报错:

0x7f8fd86169a7 std::vector<>::emplace_back<>()

原因分析

原本代码思路:在对valid_indices 赋值之前,先清空一下,然后将符合条件的数存入 valid_indices 数组。

问题在于程序使用的是多线程。

代码单线程测试了一下,也是没问题的,多线程的问题出在哪里呢?

问题就是出在赋值 emplace_back 时,如果发现 容量capacity 不够时,vector 会扩容

多个线程同时到达 vector 的 emplace_back 语句,如果发现 capacity 不够了,开始扩容。这时几个线程同时扩容,就会造成资源竞争冲突,就会报错。

而如果加上第4句,先扩容到1个很大的范围,但是clear仅仅是将成员清除,使得size为0,因此多线程 emplace_back的时候,就能够直接emplace_back了,不会发生扩容问题。

解决

多线程需要同时对同一个vector进行写入的时候,先扩容到一个值,避免各个线程单独扩容,保证程序稳定有效进行。

代码测试

不扩容和提前扩容 size 与 capacity 变化

int main() {
  std::vector<int> randy3;// 初始化: size : 0, capacity: 0
  randy3.reserve(2); // reserve  size : 0, capacity: 2
  std::cout << "reserve size: " << randy3.size() << ", capacity: " << randy3.capacity() << std::endl;
    
  std::vector<int> randy2; // 初始化: size : 0, capacity: 0
  std::cout << "1 size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;
  
  randy2.clear(); // 清空size,  size : 0, capacity: 0
  std::cout << "2 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;

  randy2.resize(2); // 扩容 capacity 为2 ,  size : 0, capacity: 0
  std::cout << "3 size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;

  randy2.clear(); // 清空size,  size : 0, capacity: 2
  std::cout << "4 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;

  randy2.emplace_back(2); // emplace_back 1 个元素,  size : 1, capacity: 2
  std::cout << "5 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;


  randy2.emplace_back(13);// 再 emplace_back 1 个元素,  size : 2, capacity: 2
  std::cout << "6 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;


  randy2.emplace_back(22); // emplace_back 第 3 个元素,  size : 3, capacity: 4
  std::cout << "7 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;
}

结果:

reserve size: 0, capacity: 2
1 size: 0, capacity: 0
2 clear size: 0, capacity: 0
3 size: 2, capacity: 2
4 clear size: 0, capacity: 2
5 clear size: 1, capacity: 2
6 clear size: 2, capacity: 2
7 clear size: 3, capacity: 4

欢迎关注公众号【三戒纪元】

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值