2014-12-03 82 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您在countFrequency()中的fseek不正确......请查看手册页的第三个参数。 – TonyB 2014-12-03 03:46:02

+0

至于countFrequency中的文件描述符,它是否应该使用相同的文件描述符,因为它指向同一个文件? – jgabb 2014-12-03 04:53:18

+0

@jgabb照片3线程...第一个从偏移量1开始,第二个从偏移量3001开始,第三个从偏移量6001开始。每个读取3000个字节。线程之一做一个fseek()来抵消1,但在它可以读取线程2接管之前。然后它做一个fseek()来抵消3001,但在它读取之前,线程3接管。线程3 fseek()到6001 ...现在线程再次得到控制,它认为它在偏移量1,实际上它是在偏移量6001 ...你看到问题...你需要同步访问,或者将整个文件读入内存并按照这种方式进行处理。 – TonyB 2014-12-03 04:59:43

相关问题