Seg Fault при чтении из файла и использовании pthread_create

Всякий раз, когда я запускаю свой код, я выполняю 4 итерации чтения файла и создания pthread, пока он не выйдет из строя с идентификатором 11.

Segfault вызван моей печатью ln: printf("%s %s\n", "Вызов lab_manifes_alignment с пакетом", *package); Но почему это вызывает segfault?

Халп?

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>

pthread_mutex_t mutex;

FILE *packageList;

void *submitPackage(void * packageReq){
    char ** package = packageReq;
    strcat(packageReq, " | sh lab_manifest_alignment.sh");
    printf("%s %s\n", "Calling lab_manifes_alignment with package", *package);
    system(packageReq);
    return NULL;
}


int main(){
    int numThreads;
    pthread_t threads[numThreads];

    //Init mutex
    if(pthread_mutex_init(&mutex, NULL)){
            fprintf(stderr, "Error initializing mutex");
    }

    int rc;
    FILE *packageList = fopen("package_list.txt", "r");
    if(packageList == NULL){
            fprintf(stderr, "ERROR: cannot open file.\n");
            return 1;
    }

    int i = 0;
    char line[128];

    while ( fgets ( line, sizeof line, packageList ) != NULL ){ 
    /* read a line spawn as many threads as needeed*/
        printf("%s %d, %s\n", "line: ",i, line);
        rc = pthread_create(&(threads[i]), NULL, submitPackage, line);

        if(rc){
            printf("ERROR: return code from pthread_create() is %d\n", rc);
            exit(EXIT_FAILURE);
        }
        i++;
    }

    numThreads = i;

    for(i = 0; i < numThreads; i++){
            pthread_join(threads[i], NULL);
    }

    fclose(packageList);
    return 0;

}


person coloradocoder    schedule 19.11.2015    source источник
comment
Вы намеренно вызываете проблемы параллелизма?   -  person this    schedule 19.11.2015
comment
Это грубо? Извините, я не использовал pthreads в течение многих лет...... В чем проблема, если есть так много вопиющих проблем?   -  person coloradocoder    schedule 19.11.2015
comment
Нет, это не грубо. Параллелизм — одна из проблем. Как я уже спрашивал ранее, это намеренно?   -  person this    schedule 19.11.2015
comment
Я не создавал никаких преднамеренных проблем, я любитель C   -  person coloradocoder    schedule 19.11.2015


Ответы (2)


pthread_t threads[numThreads]; numThreads здесь неинициализировано, вы должны выбрать максимальное значение потоков или выделить его динамически.

fgets ( line, sizeof line, packageList ) считывает 128 байт в line (размер массива), но strcat(packageReq, " | sh lab_manifest_alignment.sh"); что-то добавляет за ним. Это причина вашего segfault. Вы должны увеличить размер массива и уменьшить параметр размера в fgets.

Следующая итерация в вашем основном потоке перезаписывает ваш массив line, пока потоки работают с ним. Вы должны использовать 2D-массив или выделять буфер в каждой итерации и освобождать его в потоке после работы с ним. У каждого потока должен быть свой буфер, а не у всех одинаковый.

char ** package = packageReq; должно быть char *package = packageReq; и удалить * в printf.

person mch    schedule 19.11.2015
comment
Обратите внимание, что для моего numThreads устанавливается значение i, равное количеству строк в моем файле. После перехода от использования strcat к первому варианту здесь: строки в c, какой метод более эффективен"> stackoverflow.com/questions/1383649/ Я получил ошибку сегмента, чтобы выйти. Спасибо, я забыл подумать, что мне понадобится буфер для этих строк. - person coloradocoder; 19.11.2015
comment
Я заметил это, но во время объявления массива его значение не инициализируется и поэтому вызывает неопределенное поведение. - person mch; 19.11.2015
comment
А..спасибо..тоже..почему 2D-буфер? Разве я не мог просто создать одномерный общий буфер, использовать мьютекс и заставить каждую строку из него извлекаться и извлекаться? - person coloradocoder; 19.11.2015
comment
конечно, но поскольку только 1 поток (включая основной поток) может одновременно использовать буфер, это будет похоже на однопоточную программу. - person mch; 19.11.2015
comment
Итак, я заработал буфер... однако, когда я изменил char ** package = packageReq; в char *package = packageReq; Теперь я получаю сообщение об ошибке: не могу установить (char *) для ввода (void **) --- использование char ** package = правильно, но все равно выдает предупреждение... есть ли информация о том, как устранить это предупреждение? - person coloradocoder; 19.11.2015

Думаю проблема здесь:

char ** package = packageReq;

Попробуйте изменить:

char ** package = &packageReq;
person Viet    schedule 19.11.2015