c - Mutex - 使用线程计算文件中 char 的出现次数

标签 c multithreading pthreads mutex

您好,我正在编写一个代码,用于使用线程计算一个或多个文件中某个字母的出现次数。我必须为每个文件使用一个线程 e 使用互斥锁来修改全局总数。

这是我的代码:

typedef struct _CharFile{

    char c;
    char *fileName;

} CharFile;

pthread_mutex_t count = PTHREAD_MUTEX_INITIALIZER;
int sum = 0;

void *CountFile(void *threadarg);

int main(int argc, const char * argv[]) {

    pthread_t threads[argc-2];
    int chck, t;
    CharFile cf;

    if (argc <= 2){

        perror("Wrong inputs: need to select a letter and one or more files\n");
        exit(EXIT_FAILURE);

    } else if (argc > 51) {

        perror("Too many files\n");
        exit(EXIT_FAILURE);

    }

    for ( t=0 ; t<argc-2 ; t++ ){

        cf.c = argv[1][0];
        cf.fileName = (char *)argv[t + 2];

        chck = pthread_create(&threads[t], NULL, CountFile, (void *) &cf);
        if (chck){
            printf("ERROR; return code from pthread_create() is %d\n", chck);
            exit(EXIT_FAILURE);
        }

    }

    for (int i = 0; i < 2; i++)
        pthread_join(threads[i], NULL);

    printf("%lld occurrences of the letter %c in %lld threads\n", (long long)sum, argv[1][0], (long long)argc-2);

    return 0;
}

void *CountFile(void *threadarg){

    FILE *in;
    CharFile *cf;
    char c;
    int counter = 0;

    cf = (CharFile *) threadarg;
    in = fopen(cf->fileName, "r");

    if (in == NULL){

        perror("Error opening the file!\n");
        pthread_exit(NULL);

    }

    while (fscanf(in, "%c", &c) != EOF){

        if(c == cf->c){

            counter ++;

        }

    }

    fclose(in);

    pthread_mutex_lock(&count);
    sum += counter;
    printf("%d sum value, %d counter value \n", sum, counter);
    pthread_mutex_unlock(&count);

    pthread_exit(NULL);
}

我不知道哪里出了问题,但是使用我拥有的一些带有一堆字母的文件,结果很奇怪。

运行此行 ./a.out f file1.in lorem.txt notes.txt 两次我得到这些结果:

4 sum value, 4 counter value 
9 sum value, 5 counter value 
13 sum value, 4 counter value 
13 occurrences of the letter f in 3 threads

4 sum value, 4 counter value 
8 sum value, 4 counter value 
12 sum value, 4 counter value 
12 occurrences of the letter f in 3 threads

虽然如果我运行一个只有一个文件的更简单的命令行,计数是正确的,即 ./a.out f file1.in

5 sum value, 5 counter value 
5 occurrences of the letter f in 1 threads

感谢您的帮助。

最佳答案

我想你的问题可能出在这里:

for ( t=0 ; t<argc-2 ; t++ ){

    cf.c = argv[1][0];
    cf.fileName = (char *)argv[t + 2];

    chck = pthread_create(&threads[t], NULL, CountFile, (void *) &cf);
    if (chck){
        printf("ERROR; return code from pthread_create() is %d\n", chck);
        exit(EXIT_FAILURE);
    }

}

您向所有线程传递一个指向同一变量的指针(即 cf)。将指针传递给第一个线程后,您更改 cf 的值并将指向它的指针传递给第二个线程,依此类推。

因此,在“刚刚启动”的线程读取其值之前,主循环可能会更改 cf,即线程可能会打开另一个非预期的文件。

通过将 cf 更改为数组,确保每个线程都有自己的 cf,即每个线程一个元素。

关于c - Mutex - 使用线程计算文件中 char 的出现次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46833529/

相关文章:

c - Xcode 的 SVD 库

c - 有时 float 比 double 好吗?

.net - OpenCV多线程调用

c++ - 在多线程程序中实现动态屏障的可能方法

c++ - c++ 中 pthread 库中的互斥体是否与 Java 中的同步关键字相同

c - 如果 pthread 条件变量收到信号但互斥体被锁定,会发生什么情况?

c - 当客户端通过按 Ctrl+c 关闭时,服务器会继续处理先前的输入。为什么?

java - C和Java之间的内存分配

Java: mytextarea.setText ("hello") + Thread.sleep(1000) = 奇怪的结果

android - 创建一个在 UI 线程 Android 中更新的秒表