2017-11-02 6 views
0

Ich bin relativ neu in C im Allgemeinen und ich versuche, einen kleinen Bildfilter während der Verwendung von Pthreads zu machen. Nach ein paar Stunden mit Zeigern und Referenzen spielen um es durch den Compiler geht aber dann bekomme ich einen Segmentation Fault, ist der Code, der folgende:C++: Segmentierungsfehler auf pthread_create

#include <iostream> 
#include <opencv2/core.hpp> 
#include <opencv2/imgcodecs.hpp> 

using namespace std; 
using namespace cv; 

#define WIDTH 3 
#define HEIGHT 4 

#define NUM_THREADS 4 

struct readThreadParams{ 
    Mat img; 
    Mat out; 
    int yStart; 
    int xEnd; 
    int yEnd; 
    int xRad; 
    int yRad; 
}; 

//Find average of all pixels in WXH area 
uchar getAverage(Mat &img, Mat &out, const float x1, const float y1, const int xRad, const int yRad){ 
    //x1, y1: Pixel position being checked. xRad, yRad: how many pixels are being checked in x and y, relative to starting point. 

    uchar blue; 
    uchar green; 
    uchar red; 
    Vec3b outColor; 
    for (int c = 0; c < xRad; c++){ 
     for (int r = 0; r < yRad; r++){ 
      Vec3b intensity = img.at<Vec3b>(r, c); 
      blue =+ intensity.val[0]; 
      green =+ intensity.val[1]; 
      red =+ intensity.val[2]; 
     } 
    } 
    outColor[0] = (blue/(xRad*yRad*4)); 
    outColor[1] = (green/(xRad*yRad*4)); 
    outColor[2] = (red/(xRad*yRad*4)); 
    for (int c = 0; c< xRad; c++){ 
     for (int r = 0; r< yRad; r++) 
      out.at<Vec3b>(Point(c, r)) = outColor; 
    } 

} 


void* parallel_processing_task(void * param){ 
    //This is what each thread should do: 

    struct readThreadParams *input = (struct readThreadParams*)param; 

    Mat img = input->img; 
    Mat out = input->out; 
    const float yStart = input->yStart; 
    const float xEnd = input->xEnd; 
    const float yEnd = input->yEnd; 
    const float xRad = input->xRad; 
    const float yRad = input->yRad; 

    for (int c = 0; c < xEnd; c + xRad){ 
     for (int r=yStart; r < yEnd; r + yRad){ 
      getAverage(img, out, c, r, xRad, yRad); 
     } 
    } 
} 



int main(int argc, char *argv[]){ 

    //prepare variables 
    pthread_t threads[NUM_THREADS]; 
    void* return_status; 
    struct readThreadParams input; 
    int t; 

    Mat img = imread("image.jpg", IMREAD_COLOR); 
    int ROWS = img.rows; 
    int COLS = img.cols; 
    Mat out(ROWS, COLS, CV_8UC3); 
    input.img = img; 
    input.out = out; 
    input.xEnd = COLS; 
    input.xRad = WIDTH; 
    input.yRad = HEIGHT; 

    double t2 = (double) getTickCount(); 


    for (int r = 0; r<ROWS ; ceil(ROWS/NUM_THREADS)){ 
      input.yStart = r; 
      input.yEnd = r + ceil(ROWS/NUM_THREADS); 
      pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input);    
    } 
    for(t=0; t<NUM_THREADS; t++){ 
       pthread_join(threads[t], &return_status); 
    } 

    t2 = ((double) getTickCount() - t2)/getTickFrequency(); 

    //print execution time 
    cout << "Execution time: " << t2 << " s" << endl; 

    //result image 
    imwrite("output.png", out); 

    return(0); 
} 

ich GDB verwendet, um die Schuldigen zu finden und schaffte es so zu erhalten Was herauszufinden, es ist auf der Linie 107:

pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input); 

an dieser Stelle habe ich versucht, alle über den Ort geht, Lösungen zu finden, habe ich versucht, die folgenden:

  • Ändern der Art, wie ich die Struktur definiert, Ich mach das empfange Zeiger, die später herausfanden, funktionierte nicht.
  • Ändern der Art, wie Argumente übergeben werden (z. B. Hinzufügen oder Entfernen von (*void), wo es richtig schien), die in einem größeren Chaos von Fehler oder einfach den gleichen Fehler am Ende endete.

Außerdem in dieser Sprache neu zu sein hilft mir nicht wirklich aus, wenn die GDB bt Ausgabe zu lesen versuchen:

#0__pthread_create_2_1(newthread=optimized out>, attr=<optimized out>, start_routine=<optimized out>, arg=<optimized out>) at pthread_create.c:601 
#1 0x00011a00 in main(argc=1, argv=0x7efff394) at file.cpp:107 

Ein Teil von mir will das Problem denken, ist im Zusammenhang mit den optimized out Teile, aber nachschlagen ergibt keine Ergebnisse, oder zumindest sehe ich nicht richtig aus.

Irgendwelche Gedanken, was ich hier falsch mache? Ich würde die Hilfe sehr schätzen!

+0

„machen könnte ich m relativ neu für C im Allgemeinen ", schreiben Sie Code, der nicht in einem C-Compiler kompiliert wird, sondern in einem C++ - Compiler. – Stargateur

+0

'parallel_processing_task' sollte' nullptr' bei Erfolg, glaube ich, zurückgeben. – Galik

Antwort

3

Sie haben nicht t initialisiert, bevor es in

pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input); 

So zu verwenden ist dies wahrscheinlich nicht definiertes Verhalten führen, wie t kann jeden beliebigen Wert aufweist, der &threads[t] Zugriff ungültige Speicher

+0

Danke! Das Problem war, dass ich nie den Wert für "t" änderte, wodurch alle Jobs in den Thread verschoben wurden, auf den sie zugreifen wollte. – AegisTK

+0

@AegisTK sollten Sie dies als eine Antwort auf Ihre Frage akzeptieren. – GPPK