2014-12-03 4 views
1
#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h> 

struct thread_data { 
    FILE *fp; 
    long int offset; 
    int start; 
    int blockSize; 
    //struct word maybe? 
}; 

int words = 0; 

void *countFrequency(void* data) { 
    struct thread_data* td = data; 
    char *buffer = malloc(td->blockSize); 

    int i, c; 
    i = 0; c = 0; 
    enum states { WHITESPACE, WORD }; 
    int state = WHITESPACE; 

    fseek(td->fp, td->offset, td->start); 

    char last = ' '; 
    while ((fread(buffer, td->blockSize, 1, td->fp)) == 1) { 
    if (buffer[0]== ' ' || buffer[0] == '\t') { 
     state = WHITESPACE; 
    } else if (buffer[0] == '\n') { 
     //newLine++; 
     state = WHITESPACE; 
    } else { 
     if (state == WHITESPACE) { 
     words++; 
     } 
     state = WORD; 
    } 
    last = buffer[0]; 
    } 

    free(buffer); 
    pthread_exit(NULL); 
    return NULL; 
} 

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

    int nthreads, x, id, blockSize, len; 
    //void *state; 
    FILE *fp; 
    pthread_t *threads; 

    fp = fopen("file1.txt", "r"); 

    printf("Enter the number of threads: "); 
    scanf("%d", &nthreads); 
    struct thread_data data[nthreads]; 
    threads = malloc(nthreads * sizeof(pthread_t)); 

    fseek(fp, 0, SEEK_END); 
    len = ftell(fp); 
    printf("len= %d\n", len); 

    blockSize = (len + nthreads - 1)/nthreads; 
    printf("size= %d\n", blockSize); 

    for (id = 0; id < nthreads; id++) { 
    data[id].fp = fp; 
    data[id].offset = blockSize; 
    data[id].start = id * blockSize + 1; 
    //maybe data[id]. word struct 
    } 
    //LAST THREAD 
    data[nthreads-1].start=(nthreads-1)*blockSize+1; 

    for (id = 0; id < nthreads; id++) 
    pthread_create(&threads[id], NULL, &countFrequency,&data[id]); 

    for (id = 0; id < nthreads; id++) 
    pthread_join(threads[id],NULL); 

    fclose(fp); 

    printf("%d\n",words); 
    return 0; 
} 

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

Может ли кто-нибудь сказать мне, почему он дает мне неправильное количество слов?

ответ

1

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

Этот дефект дизайна должен быть адресован первым.

+0

@jgabb Ваш fseek в countFrequency() неверен ... посмотрите на страницу руководства для своего третьего аргумента. – TonyB

+0

Что касается дескриптора файла в countFrequency, не следует ли использовать тот же дескриптор файла, поскольку он указывает на тот же файл? – jgabb

+0

@jgabb Изображение это, 3 потока ... первый начинается со смещения 1, второй начинается со смещения 3001, третий начинается со смещения 6001. Каждый из них должен читать 3000 байт. В потоке один делает fseek() до смещения 1, но прежде чем он сможет прочитать поток 2, берет на себя. Затем он выполняет fseek() для смещения 3001, но прежде чем он сможет его прочитать, поток 3 берет верх. Тема 3 fseek() to 6001 ... Теперь поток получает контроль снова, и он ДУМАЕТ, что он находится на смещении 1, когда на самом деле он находится в смещении 6001 ... вы видите проблему ... вам нужно либо синхронизировать доступ , или прочитать весь файл в памяти и обработать его таким образом. – TonyB

Смежные вопросы