Ошибка сегментации при использовании структур в pthreads - PullRequest
0 голосов
/ 22 апреля 2020

Я пытался разделить запись в файл с потоками и для этого я пытаюсь использовать структуры для хранения начальной и конечной позиций файла. Код компилируется, однако, я получаю ошибку сегментации, когда код пытается создать несколько потоков и не выполняет код потока. Я правильно использую структуры?

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX_THREADS 100
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

struct position {
    int start;
    int end;
};

 void *ThreadJob(void *id) //what the thread should do
 {
    pthread_mutex_lock(&mutex);
    struct position *b;
    printf("\nstart: %d \nend: %d\n", (*b).start, (*b).end);
    double* arrayPtr = malloc( 100000* sizeof(double));
    FILE *file;
    FILE* nFile; // New file
    double n; 
    nFile = fopen("newTriData1.txt","a");
    char line[128]; //the lines of the txt file
    file = fopen("TriData1.txt", "r");
    long tid;
    tid = (long)id;
    int count = 0;
    while (fgets(line, 128, file))  //gets the lines from the txt file - line by line
    { 
        sscanf(line ," %lf", &arrayPtr[count]); //converts the value on the line into a double to manipulate     
        count++; //increment the count
    }
    free(arrayPtr);
    while((*b).start<(*b).end){
        double x = (sqrt(8*arrayPtr[(*b).start]+1) - 1) / 2; //equation to detect triangular numbers 
        if (x == floor(x)) //checks if the value has a remainder. The value should be a whole number
            {
                fprintf(nFile, "\nNumber %s: Triangular\n", line); //if true writes the value and triangular 
            }
        else 
            {
                fprintf(nFile, "\nNumber %s: Not Triangular\n", line);

            }
        (*b).start++;
    }
    (*b).start=(*b).end;
    (*b).end = ((*b).end + (*b).end);
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
}

 int main (void) //main
 {
    struct position a;
    (a).start=0;
    int line_count;
    FILE *file;
    double count_lines = 1.0;
    char check;
    double i = 4;
    file = fopen("TriData1.txt", "r");
    double divider;
    check = getc(file);
    while (check != EOF)
    {
        if (check == '\n')
        {
            count_lines = count_lines + 1;
        }

        check = getc(file); //take the next character from the file
    }
    printf("cl: %f", count_lines);
    double vo = fmod(count_lines,4); //using fmod to find which number divides the line count into equal parts for the number of threads
    if (fmod(count_lines,4) == 0) {
    double value1 = count_lines/4;
    double value2 = count_lines/4;
    double value3 = count_lines/4;
    double value4 = count_lines/4;

    printf("v1: %f \n v2: %f \n v3: %f \n v4: %f", value1,value2,value3,value4);
    divider =4;
    line_count = count_lines/4;
    (a).end=line_count;
    }
    else
    {
        while (fmod(count_lines, i) != 0) //if the value is not divisible by 4 then i will increment until a suitable divider is found
        {
            i++;
            divider = i;
            line_count = count_lines/i;
            printf("divider: %f", divider);
        }
        (a).end=line_count;
    }

    fclose(file); //close file.
    printf("There are %f lines in this file\n", count_lines);
    printf("\nstart: %d \nend: %d\n", (a).start, (a).end);
    pthread_t threads[MAX_THREADS];
    int thread;
    long threadNum ;
    for(threadNum=0; threadNum<divider; threadNum++){
       printf("Creating thread %ld\n", threadNum);
       thread = pthread_create(&threads[threadNum], NULL, ThreadJob, (void *)threadNum);
       if (thread){
          printf("ERROR; %d\n", thread);
          exit(-1);
       }
    }
    pthread_exit(NULL);
    return 0;
 }

1 Ответ

3 голосов
/ 22 апреля 2020

Почти каждая строка вашего кода неверна, но большинство ваших ошибок просто заставят вашу программу делать не то, а не взламывать sh полностью. Вот только ошибки, которые делают вашу программу cra sh:

struct position *b;
printf("\nstart: %d \nend: %d\n", (*b).start, (*b).end);

Это, вероятно, приведет к segfault, потому что вы не можете разыменовать неинициализированный указатель.

free(arrayPtr);
while((*b).start<(*b).end){
    double x = (sqrt(8*arrayPtr[(*b).start]+1) - 1) / 2; //equation to detect triangular numbers 

Это может вызвать segfault, потому что Вы не можете использовать память после того, как освободите ее. Кроме того, последняя строка этого кода, вероятно, будет иметь значение segfault, поскольку вы все еще не инициализировали b.

    (*b).start++;
}
(*b).start=(*b).end;
(*b).end = ((*b).end + (*b).end);

Все эти строки, вероятно, будут иметь значение segfault, поскольку b все еще не инициализирован.

Честно говоря, вы должны отказаться от продвинутых тем, таких как темы, и постараться понять основы C.

...