多线程分段错误(for循环)
Posted
技术标签:
【中文标题】多线程分段错误(for循环)【英文标题】:Multithreading segmentation fault (for loop) 【发布时间】:2018-03-16 11:17:27 【问题描述】:为什么下面的代码给我一个分段错误:
#include<iostream>
#include<thread>
#include<vector>
using namespace std;
double f(double a, double b, double* c)
*c = a + b;
int main()
vector<double> a =1,2,3,4,5,6,7,8;
vector<double> b =2,1,3,4,5,2,8,2;
int size = a.size();
vector<double> c(size);
vector<thread*> threads(size);
for (int i = 0; i < size; ++i)
thread* t = new thread(f, a[i], b[i], &c[i]);
threads.push_back(t);
for (vector<thread*>::iterator it = threads.begin(); it != threads.end(); it++)
(*it)->join();
cout << "Vector c is: ";
for (int i =0; i < size; ++i)
cout << c[i] << " ";
我知道分段错误发生在使用迭代器的 for 循环内,但我不确定为什么。
【问题讨论】:
没有什么可以保护对 c 的访问免受并发访问。您不能像在单线程程序中那样从线程中读取/写入变量。您需要使用锁(如 std::mutex)或使用 std::atomic 变量来同步访问。 @JesperJuhl:我不确定,但我相信这里不需要同步。任何地方都没有并发写访问。 【参考方案1】:vector<thread*> threads(size);
声明创建一个向量,其中包含size
数量的默认初始化thread*
对象,这些对象是nullptr
。
然后使用push_back
插入额外的非空对象,但空对象保留在那里,并且在最后迭代向量时取消引用它们。
【讨论】:
【参考方案2】:您应该将for
循环更改为如下所示:
for (int i = 0; i < size; ++i)
thread *t = new thread(f, a[i], b[i], &c[i]);
threads[i] = t;
在结束之前,你应该delete
你的堆分配thread
s。
for (auto thread : threads)
delete thread;
更好的是简单地使用:
vector<thread> threads(size);
for (int i = 0; i < size; ++i)
threads[i] = thread(f, a[i], b[i], &c[i]);
for (auto& thread : threads)
thread.join();
顺便说一句,您应该注意编译器警告。改变
double f(double a, double b, double *c) *c = a + b;
到
void f(double a, double b, double *c) *c = a + b;
【讨论】:
以上是关于多线程分段错误(for循环)的主要内容,如果未能解决你的问题,请参考以下文章