2016-07-12 8 views
-2

Ich schrieb einen einfachen C++ - Code, um den minimalen Wert eines Vektors zu finden, finden Sie weiter unten. Er kompiliert sowohl in VC++ als auch in g ++, läuft aber auf einem Segmentierungsfehler auf dem letzteren. Ich kann nicht unterscheiden, ob mein Code ein UB enthält oder das g ++ einen Fehler enthält. Kann jemand einen Fehler in meinem Code erkennen?Thread Beispiel, Segmentierung Fehler

Der segfault entsteht bei thread :: join().

einige Debug-Informationen

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))] 

Hier ist der Code

#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; 
} 
+1

Bei der Diagnose eines Segmentfehlers ist es nützlich, ein Backtrace zu erhalten und zu wissen, wo der Segmentfehler auftritt. – md5i

+0

Das Ausführen durch Valgrind/Helgrind zeigte keine Probleme unter Linux/g ++ - 5.3 – Arunmu

+0

Anspruch auf Laufzeitfehler von [Code, der nicht kompiliert] (http://coliru.stacked-crooked.com/a/19c20c61347e8a2f) klingt komisch. –

Antwort

0

ich in das Makefile sah, und -static ohne -whole-archive verwendet wurde, die unter g Problem führt ++ nach https://gcc.gnu.org/ml/gcc-help/2010-05/msg00029.html

Es teilt mit, dass wenn libstdC++ ohne __thread Unterstützung und Verknüpfung gegenkonfiguriert istist statisch, dies kann aufgrund eines libstdC++ - Fehlers auftreten.

1

Sie sollten -pthread als Option für jede Kompilierungsphase mit GCC (g ++) verwenden, anstatt mit -lpthread zu verknüpfen.

Es gibt mehr Sachen beteiligt als einfache Verknüpfung mit diesem Flag tatsächlich.

+0

Danke für die Info. Ich habe auch versucht - pthread statt -lpthread, und selbst hat das Problem nicht gelöst. – DanielTuzes

+0

Ich habe nie gesagt, dass es tatsächlich Ihr Problem über die Probe, die ich gepostet habe, löst. –