线程示例,分段错误

Posted

技术标签:

【中文标题】线程示例,分段错误【英文标题】:thread example, segmentation fault 【发布时间】:2016-07-12 20:16:03 【问题描述】:

我编写了一个简单的 C++ 代码来查找向量的最小值,请参见下文。它在 VC++ 和 g++ 上都可以编译,但在后者上会出现分段错误。我无法区分我的代码是否包含 UB 或 g++ 是否包含错误。有人能找出我的代码中的任何错误吗?

段错误出现在 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;

【问题讨论】:

在诊断段错误时,获取回溯并了解段错误发生的位置很有用。 通过 valgrind/helgrind 运行它在 linux/g++-5.3 上没有显示任何问题 从code that doesn't compile 声明运行时错误听起来很奇怪。 @πάντα ῥεῖ 也许包括 可以是一个解决方案 @DanielTuzes 根据需要提供minimal reproducible example。否则你的问题就是题外话,就这么简单。这是你的错,不是我的。 【参考方案1】:

我查看了Makefile,没有-whole-archive使用-static,导致根据https://gcc.gnu.org/ml/gcc-help/2010-05/msg00029.html在g++下出现问题

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

【讨论】:

【参考方案2】:

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

实际上,除了使用该标志的简单链接之外,还涉及更多内容。

【讨论】:

感谢您的信息。我也试过-pthread而不是-lpthread,本身并没有解决问题。 我从未说过它实际上解决了我发布的示例之外的问题。

以上是关于线程示例,分段错误的主要内容,如果未能解决你的问题,请参考以下文章

Boost 线程中的分段错误 tls_destructor

在新线程内调用OpenCV函数Canny()会导致分段错误

带有 std::promise 的 C++11 分段错误

警报处理程序中交换上下文后的分段错误

vector::size 和分段错误

pyqt5 中的分段错误(核心转储)