将Mutex和lock_guard与C++中的向量一起使用
Using Mutex and lock_guard with a vector in C++
我是C++线程领域的新手。关于mutex
和lock_guard
的用法,我需要你的帮助(这部分无关紧要)。我有一个主要功能和一个次要功能。
请告诉我为什么在添加lock_guard(mtx)
时多线程不起作用;当我移除它时,它运行得更快,但错误。你能帮我吗?
我需要正确访问向量vec
并启用线程。
#include <vector>
#include <thread>
std::mutex mtx;
void threadCall(std::vector<int> &vec, int start, int end){
std::lock_guard<std::mutex> guard(mtx);
for(int i=start; i<end; i++)
vec[i] = i;
}
void ThreadFunc(std::vector<int> vec){
std::vector<std::thread> threads(2);
threads[0] = std::thread(&threadCall, std::ref(vec), 0, 10);
threads[1] = std::thread(&threadCall, std::ref(vec), 10, 20);
threads[0].join();
threads[1].join();
}
int main(){
std::vector<int> vec(20);
ThreadFunc(vec);
return 0;
}
互斥锁阻止线程并行执行任何工作。只要你能保证每个线程不会写入向量的同一部分,你就根本不需要互斥锁。
另一个问题是通过值传递向量。你应该通过参考:
void threadCall(std::vector<int>& vec, int start, int end){
for(int i=start; i<end; i++)
vec[i] = i;
}
void ThreadFunc(std::vector<int>& vec){
std::vector<std::thread> threads(2);
threads[0] = std::thread(&threadCall, std::ref(vec), 0, 10);
threads[1] = std::thread(&threadCall, std::ref(vec), 10, 20);
threads[0].join();
threads[1].join();
}
int main(){
std::vector<int> vec(20);
ThreadFunc(vec);
}
现场演示。
首先,停止按值传递向量,传递引用。在解决了这个问题之后,您的特定示例实际上根本不需要互斥。你的矢量有一个固定的大小:
std::vector<int> vec(20);
所有元素都是从一开始就默认构建的。既然你所做的只是分配:
vec[i] = i;
矢量不会重新分配任何存储或调整其项目计数。因此,没有必要将对向量的访问锁定为一个整体。再加上每个线程都在一个单独的子范围上操作,不存在任何数据竞争。您不需要同步原语。
问题是互斥被第一个线程占用,第二个线程在释放之前无法工作。
因此,本质上,您会收到一个多线程应用程序,其中所有线程都串行地执行它们的工作。
你可以移动你的警卫进入循环
for(int i=start; i<end; i++) {
std::lock_guard<std::mutex> guard(mtx);
vec[i] = i;
}
这将使线程有可能在传递的向量上协同工作。
但是:
您需要考虑到多个线程并不总是能提高性能,因为并发!=并行性。
我希望这个应用程序以这种方式实际上比单线程实现慢,因为以下内容:
- 线程通过
mutex
相互阻塞,因此一次只运行一个线程 - 您花费时间在线程之间的上下文切换上
解决方案理念:
如果你想真正并行地运行它,你需要让线程处理独立的数据,然后连接结果。
相关文章:
- 将 boost::odeint 与向量类一起使用,而无需调整向量的大小
- 将 [][] 运算符与向量一起使用?
- 如何在 c++ 中将变换与对的向量一起使用
- 与unordered_map向量一起使用的最小示例中的scoped_allocator_adaptor错误
- 如何将基于范围的 for 循环与未来的<T>向量一起使用
- 如何将"查找"和"substr"函数与向量一起使用?
- 如何将find_first_not_of与字符串向量一起使用
- 将Mutex和lock_guard与C++中的向量一起使用
- 将赋值运算符与 unique_ptr 向量一起使用
- 将 at() 与自定义对象的向量一起使用时的分割错误
- 自定义分配器有时会与stl向量一起崩溃
- 将 C++ 中的"extern C"与 ctypes 的向量一起使用
- 将memcpy与Eigen类型的向量一起使用安全吗
- 将赋值运算符与类实例和向量一起使用
- 将二叉搜索与向量一起使用
- 在C++中将一个向量与另一个向量一起排序
- 将自定义类与向量一起使用:'std::vector'默认构造函数错误
- 与向量一起使用的C++可为Null/可选项的整数
- 与指针向量一起使用的最佳智能指针是什么
- 如何将提取运算符 (>>) 与向量一起使用<bool>?