[C/C++标准库]_[初级]_[std::vector的多线程读写问题]

本文讨论了在多线程场景下,C++ std::vector在进行push_back和下标访问时可能出现的崩溃问题。尽管可能认为这些操作是线程安全的,但在并发环境中仍可能导致数据不一致。文中通过代码示例展示了问题的发生,并提到了在Visual Studio C++ 2010 SP1环境下遇到的内存异常。为了解决这个问题,作者建议暂时使用C数组作为替代方案。
摘要由CSDN通过智能技术生成


场景:

1. 有时候需要使用vector 或 map作为多线程的共享变量, map是tree结构, 读和写方法都不是线程安全的, 即同时读写会有崩溃的现象.

2. std::vector直观来说只用push_back和[] 下标访问操作应该没问题,push_back往后边加对象, 索引值只访问已经存储的变量(预先求size).注意, 这里不会删除vector元素.

可惜,这种多线程操作还是会崩溃. 单线程写和单线程读!!!

看代码:

test_vector.cpp

#include "gtest/gtest.h"
#include <vector>
#include <iostream>
#include <Windows.h>
#include "pthread.h"

class A
{
public:
	A(int i):i_(i){}
	int i_;
};

void* first = NULL;
void* second = NULL;

static void* Push(void* data)
{
	std::vector<A*>& vec = *(std::vector<A*>*)data;
	vec.push_back(new A(-1));
	first = std::addressof(vec._Myfirst);
	//std::cout << first << std::en
可以使用std::mutex来保护变量edges,确保多个线程不会同时访问它。以下是示例代码: ```c++ vector<Edge1D_Result> edges; std::mutex edges_mutex; void processEdges() { // 处理edges之前先获取锁 edges_mutex.lock(); for (int i = 0; i < m; i++) { vector<Edge1D_Result> temp_edges = Extract1DEdgeCircle.Get1DEdge(RoiMat, m_vpdEquinoxPoints[i], m_dMeasureLength, m_dMeasureHeight, m_vdMeasureAngle[i], m_dSigma, m_nThresholdCircle, m_nTranslationCircle == 1 ? Translation::Poisitive : Translation::Negative, Selection::Strongest); // 释放锁,让其他线程可以访问edges edges_mutex.unlock(); // 处理临时的edges for (int i = 0; i < temp_edges.size(); i++) { m_vpdEdgePoints.push_back(temp_edges[i].m_pdEdgePoint); m_vdEdgeGradient.push_back(temp_edges[i].m_dGradient); } // 获取锁,再次访问edges edges_mutex.lock(); // 将临时的edges合并到主线程的edges中 edges.insert(edges.end(), temp_edges.begin(), temp_edges.end()); } // 释放锁 edges_mutex.unlock(); } // 创建多线程 std::vector<std::thread> threads; for (int i = 0; i < num_threads; i++) { threads.push_back(std::thread(processEdges)); } // 等待所有线程结束 for (auto& thread : threads) { thread.join(); } ``` 在这个示例中,我们使用了std::mutex来保护变量edges。在每个线程中,我们首先获取锁,并提取出一批1D边缘。然后,我们释放锁,让其他线程可以访问edges,同时在当前线程中处理临时的edges。最后,我们再次获取锁,将临时的edges合并到主线程的edges中。这样,我们就可以使用多线程加速处理for循环中的任务,并且确保变量edges的安全访问。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Peter(阿斯拉达)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值