Я уже несколько месяцев ломаю голову над этой программой. Это было задание класса, которое я взял в прошлом семестре, и пока я проходил, я никогда не смог бы правильно выполнить это одно задание (Seg Fault). Я приветствую любую помощь или советы, но я очень благодарен за объяснения ответов на вопросы.C проблема с сегментацией сегментации многопоточной рассылки
Эта программа должна получить имя файла, которое содержит список имен файлов (240 для моего примера). Эти файлы находятся в папке в том же каталоге, что и список и программа. Предполагается, что эта программа возьмет этот список и проанализирует его для 4 потоков, равномерно разбивая имена файлов для каждого потока (60 на поток для моего примера). Каждый поток затем принимает этот список из 60 имен файлов и каждый раз открывает каждый файл, выполняя функцию WordCount для каждого файла. После того как потоки выполняют свои задачи, они должны печатать результаты для каждого файла, чтобы каждый поток в своем собственном блоке (то есть результаты Thread1, результаты Thread2, результаты 3-го и т. Д.).
Я отлаживал совсем немного и знаю, что вплоть до создания нитей все работает так, как предполагается. Моя проблема, кажется, во время запуска/выполнения потока. Я попытался добавить мьютекс в микс, но, к сожалению, это не помогло. Мне кажется, что что-то не хватает или что-то думает, потому что некоторые из моих товарищей по классу показали мне гораздо более компактный код. Пожалуйста помогите. Благодаря!
Вот Main:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MaxLine 200
#define NUMTHREADS 4
char Line[MaxLine];
pthread_mutex_t Lock = PTHREAD_MUTEX_INITIALIZER;
typedef struct thread {
int id;
char file;
}ThreadData;
/* ThreadFunction will give each thread its processes to execute */
void *threadFunc (void *td) {
ThreadData *data = (ThreadData*)td;
int thread_num=data->id;
char filename=data->file;
printf("thread debug tid: %d and file: %c",thread_num, filename);
pthread_mutex_trylock(&Lock);
FILE *fn = fopen(filename, "r");
if (fn == NULL) {
error("ERROR: Opening file");
return 1;
}
while (fgets(Line, sizeof(Line), fn) != NULL) {
CountWord(thread_num, Line);
}
fclose(fn);
free(data);
pthread_mutex_unlock(&Lock);
pthread_exit(NULL);
}
int main(int argc, char *argv[]){
char buf[20];
int c, i, t, tnum, QUEUETOTAL;
pthread_t thread[NUMTHREADS];
ThreadData td[NUMTHREADS];
if (argc != 2){
fprintf(stderr,"ERROR: Usage must be Countfile filename\n", argv[0]);
exit(0);
}
char const* const filename = argv[1];
FILE* file = fopen(filename, "r");
if (file == 0){
printf("Could not open file!\n");
exit(0);
}
/* Count iterations of while loop to divide files among threads. */
while (fgets(Line, sizeof(Line), file)){
QUEUETOTAL++;
}
/* Divide work for threads. */
int thread2taskstart=(QUEUETOTAL/NUMTHREADS); //60
int thread3taskstart=(QUEUETOTAL/NUMTHREADS)*2; //120
int thread4taskstart=(QUEUETOTAL/NUMTHREADS)*3; //180
// QUEUETOTAL = 240
rewind(file);
FILE *tempfile1 = fopen("temp1.txt","w");
for (i=0; i<thread2taskstart; i++) {
// populate tempfile1 with entries 1-60
if(fgets(Line,sizeof(Line),file)!=NULL) {
fputs(Line,tempfile1);
//printf("Debug temp1: %s",Line);
}
}
fclose(tempfile1);
FILE *tempfile2 = fopen("temp2.txt","w");
for (i=thread2taskstart; i<thread3taskstart; i++) {
// populate tempfile2 with entries 60-120
if(fgets(Line,sizeof(Line),file)!=NULL) {
fputs(Line,tempfile2);
//printf("Debug temp2: %s",Line);
}
}
fclose(tempfile2);
FILE *tempfile3 = fopen("temp3.txt","w");
for (i=thread3taskstart; i<thread4taskstart; i++) {
// populate tempfile3 with entries 120-180
if(fgets(Line,sizeof(Line),file)!=NULL) {
fputs(Line,tempfile3);
//printf("Debug temp3: %s",Line);
}
}
fclose(tempfile3);
FILE *tempfile4 = fopen("temp4.txt","w");
for (i=thread4taskstart; i<=QUEUETOTAL; i++) {
// populate tempfile3 with entries 180-240
if(fgets(Line,sizeof(Line),file)!=NULL) {
fputs(Line,tempfile4);
//printf("Debug temp4: %s",Line);
}
}
fclose(tempfile4);
fclose(file);
/* Prepare parameters & launch (4) threads. Wait for threads
to finish & print out results as specified in assignment. */
printf("Counting files …\n");
for(t=0;t<NUMTHREADS;t++){
tnum=t+1;
snprintf(buf, "temp%d.txt", tnum);
printf("debug tnum and array: %d and %s\n",tnum, buf);
td[t].id = tnum;
td[t].file = buf;
// Creates a new thread for each temp file.
pthread_create(&thread[t], NULL, threadFunc, td);
}
// Joins threads.
printf("debug: printing threads \n");
for(t=0;t<NUMTHREADS;t++){
pthread_join(thread[t], NULL);
printf("------------------------- Processes finished for Thread %d ----------------------- \n",t+1);
}
return 0;
}
Вот граф Функция:
#include <stdio.h>
int CountWord(int tinfo, char cfile){
int i;
int ccount = 0;
int wcount = 0;
int lcount = 0;
FILE *fname;
char fn[strlen(cfile) + 18];
sprintf(fn, "./CountingFolder/%s", cfile);
printf("Debug: %s\n", fn);
fname = fopen(fn, "r");
if (fname == NULL) {
error("ERROR: Opening file");
}
while ((i = fgetc(fname)) != EOF){
if (i == '\n') {
lcount++;
}
if (i == '\t' || i == ' '){
wcount++;
}
ccount++;
}
printf("Threadid %d processes %s which has %d characters, %d words and %d lines\n", tinfo, cfile, ccount, wcount, lcount);
fclose(fname);
return 0;
}
Вы используете 'pthread_mutex_trylock', не проверяя результат.Что происходит, когда не удалось получить блокировку? – Kninnug
в функции: CountWord(): когда файл не открывается, НЕ пытайтесь прочитать из файла – user3629249
в функции: CountWord(): в цикле «while»: рассмотрите условие, в котором строка во входном файле содержит некоторые комбинация вкладок и пробелов без других символов, включая/особенно в начале строки. И правильный текст имеет 2 пробела после окончания каждого предложения. Предложите: 1) искать stackoverflow для примеров (возможно, без нескольких потоков) извлечения слов из файла. Хорошие примеры будут иметь две государственные машины, реализованные в словах и не в словах. начать в состоянии не в словах. – user3629249