【问题标题】:Multithreading segmentation fault (for loop)多线程分段错误(for循环)
【发布时间】: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:我不确定,但我相信这里不需要同步。任何地方都没有并发写访问。

标签: c++ multithreading vector segmentation-fault


【解决方案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你的堆分配threads。

    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; }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-21
      • 1970-01-01
      • 1970-01-01
      • 2021-06-29
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 2016-06-18
      相关资源
      最近更新 更多