C++ | 多线程使用vector

多线程使用vector

文章目录

  • 多线程使用vector
    • 场景描述
    • 原因分析
    • 解决
    • 代码测试
      • 不扩容和提前扩容 size 与 capacity 变化
      • 欢迎关注公众号【三戒纪元】

场景描述

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

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: 0randy3.reserve(2); // reserve  size : 0, capacity: 2std::cout << "reserve size: " << randy3.size() << ", capacity: " << randy3.capacity() << std::endl;std::vector<int> randy2; // 初始化: size : 0, capacity: 0std::cout << "1 size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;randy2.clear(); // 清空size,  size : 0, capacity: 0std::cout << "2 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;randy2.resize(2); // 扩容 capacity 为2 ,  size : 0, capacity: 0std::cout << "3 size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;randy2.clear(); // 清空size,  size : 0, capacity: 2std::cout << "4 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;randy2.emplace_back(2); // emplace_back 1 个元素,  size : 1, capacity: 2std::cout << "5 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;randy2.emplace_back(13);// 再 emplace_back 1 个元素,  size : 2, capacity: 2std::cout << "6 clear size: " << randy2.size() << ", capacity: " << randy2.capacity() << std::endl;randy2.emplace_back(22); // emplace_back 第 3 个元素,  size : 3, capacity: 4std::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

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

本文链接:https://my.lmcjl.com/post/1581.html

展开阅读全文

4 评论

留下您的评论.