Ошибка сегментации при попытке создать несколько потоков для файлового ввода-вывода: - PullRequest
1 голос
/ 03 июня 2019

Я сталкиваюсь с ошибкой сегментации при запуске следующей программы.Я
пытаюсь создать многопоточную программу, которая выполняет 100 раз:

  1. Откройте файл.
  2. Прочитайте последнюю строку файла (каждая строка содержит число).
  3. Добавьте 3 к номеру.
  4. Добавьте новый номер в конце файла.
  5. Закройте файл.Количество потоков указывается пользователем.Когда я создаю 2 потока, этот код выполняется правильно, но когда я пытаюсь создать 1 или число, отличное от 2, он показывает ошибку сегментации.

Я использую семафор для синхронизации между потоками.У вас есть идеи, почему это происходит?

Часть main:

    for(i=0;i<NumberOfThreads;i++)  {
        if (pthread_create( pid[i], NULL, subthread, NULL ) != 0) {
            fprintf(stderr, "pthread_create failed with i = %d. errno = %d, %s\n",i, errno, strerror(errno));
            break;
        }
    }

    for(i=0;i<NumberOfThreads;i++)  {
        pthread_join(*pid[i], NULL);
    }   
    return 0;
}

void *subthread(void) {
    int i ;
    int temp ;
    char ch;
    int offset =0 ;
    FILE * fd1 ;
    FILE * fd2 ;
    for(i=0 ;i<100;i++) {
        sem_wait(&sem1);
        fd1 = fopen (NameOfFile,"r");
        fseek (fd1,-2,SEEK_END);
        offset=-2;
        while((ch=getc(fd1)) !='\n')
        {   
            offset=offset-1;
            fseek (fd1,offset,SEEK_END);
        }
        fscanf(fd1,"%d",&temp); 
        fclose(fd1);
        fd2 = fopen (NameOfFile,"a");
        temp=temp+3;
        fprintf(fd2,"\n%d",temp);
              printf("%d\n",temp);
        fclose(fd2);
        sem_post(&sem1);
    }
    pthread_exit(0);
}

Это только часть кода.

КогдаЯ запускаю код и даю 1 поток в качестве входа, он показывает ошибку сегментации.Для 2 потоков выполнение корректно.Для более чем двух потоков он снова показывает ошибку сегментации

Когда я пытаюсь отладить, чтобы увидеть, что вызывает ошибку сегментации, журнал сообщает, что функция PTHREAD_CREATE вызывает ее.

1 Ответ

3 голосов
/ 03 июня 2019

Для pthread_create() указатель, переданный в качестве первого аргумента, должен указывать на допустимое местоположение, где pthread_create() записывает идентификатор потока.Но, как вы сказали в комментарии, pid определяется как

    pthread_t * pid[NumberOfThreads+1];

, который представляет собой массив указателей, которые изначально не указывают на допустимое местоположение.Они могут быть NULL или не определены в зависимости от того, как определен массив.

Я бы посоветовал вам изменить определение на

   pthread_t pid[NumberOfThreads+1];

и вызвать pthread_create(pid+i,....) или pthread_create(&pid[i],...); и использовать pid[i] вместо *pid[i] для других pthread_...() вызовов

...