线程示例,分段错误

时间:2016-07-12 20:16:04

标签: c++ c++11 segmentation-fault g++ thread-safety

我编写了一个简单的C ++代码来查找向量的最小值,如下所示。它在VC ++和g ++上编译,但在后者上运行分段错误。我不能分辨我的代码是否包含UB或g ++包含错误。有人可以识别我的代码中的任何错误吗?

segfault出现在thread :: join()。

一些调试信息

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) where
#0  0x0000000000000000 in ?? ()
#1  0x00000000004688f7 in std::thread::join() ()
#2  0x0000000000000000 in ?? ()
(gdb) thread
[Current thread is 1 (Thread 0x7c6880 (LWP 24015))]

这是代码

#include <iostream>
#include <random>
#include <thread>
#include <vector>
#include <algorithm> 
using namespace std;

void find_min(vector<double>& x, double& min_val, int& min_id)
{
    min_id = distance(x.begin(), min_element(x.begin(), x.end()));
    min_val = x[min_id];
}

void find_part_min(vector<double>& x, vector<int>& min_ids, vector<double>& min_vals, int id)
{
    int start_id = (x.size()*id) / min_vals.size();
    int end_id = (x.size()*(id + 1)) / min_vals.size();
    for (int i = start_id; i < end_id; ++i)
    {
        if (x[i] < min_vals[id])
        {
            min_ids[id] = i;
            min_vals[id] = x[i];
        }
    }
}


int main()
{
    // define variables
    int Nthreads = 16;
    vector<double> x(256 * 256);
    int min_id = 0;
    double min_val = 0;

    // fill up vector with random content
    mt19937 gen(0);
    uniform_real_distribution<> dis(0, 1);
    generate(x.begin(), x.end(), bind(dis,gen));

    // find min serial
    find_min(x, min_val, min_id);
    cout << min_id << "\t" << min_val << endl;

    // initilaize variables for parallel computing
    vector<double> min_vals(Nthreads, numeric_limits<double>::infinity());
    vector<int> min_ids(Nthreads, -1);
    vector<thread> myThreads;

    for (int id = 0; id < Nthreads; ++id) // define each thread
    {
        thread myThread(find_part_min, ref(x), ref(min_ids), ref(min_vals), id);
        myThreads.push_back(move(myThread));
    }
    for (int id = 0; id < Nthreads; ++id)
        myThreads[id].join(); // part-calculations are finished

    // merging the results together
    min_val = numeric_limits<double>::infinity();
    min_id = -1;
    for (int i = 0; i < Nthreads; ++i)
    {
        if (min_vals[i] < min_val)
        {
            min_val = min_vals[i];
            min_id = min_ids[i];
        }
    }

    cout << min_id << "\t" << min_val << endl;

    return 0;
}

2 个答案:

答案 0 :(得分:1)

您应该使用-pthread作为GCC(g ++)每个编译阶段的选项,而不是-lpthread的链接。

实际上涉及的内容比使用该标志的简单链接更多。

答案 1 :(得分:0)

我查看了Makefile,-static在没有-whole-archive的情况下使用,根据https://gcc.gnu.org/ml/gcc-help/2010-05/msg00029.html

导致了g ++下的问题

它告诉我如果libstdc ++配置没有__thread支持并且与-lpthread的链接是静态的,这可能是由于libstdc ++错误而发生的。