c - 如何让多个线程互不干扰地读取多个文件?

标签 c thread-safety pthreads mutex

我正在研究互斥量,但我被困在一个练习中。对于给定目录中的每个文件,我必须创建一个线程来读取它并显示其内容(如果顺序不正确也没问题)。

到目前为止,线程正在运行这个函数:

void * reader_thread (void * arg)
{   

    char * file_path = (char*)arg;
    FILE * f;
    char temp[20];
    int value;

    f=fopen(file_path, "r");
    printf("Opened %s.\n",file_path);

    while (fscanf(f, "%s",temp)!=EOF)
        if (!get_number (temp, &value)) /*Gets int value from given string (if numeric)*/
             printf("Thread %lu -> %s: %d\n", pthread_self(), file_path, value );

    fclose(f);
    pthread_exit(NULL);

}

由接收 DIR 指针的函数调用,该指针先前由 opendir() 创建。 (我在这里省略了一些错误检查以使其更清晰,但我根本没有发现任何错误。)

int readfiles (DIR * dir, char * path)
{

    struct dirent * temp = NULL;        
    char  * file_path;
    pthread_t thList [MAX_THREADS];
    int nThreads=0, i;

    memset(thList, 0, sizeof(pthread_t)*MAX_THREADS);
    file_path=malloc((257+strlen(path))*sizeof(char));      

    while((temp = readdir (dir))!=NULL && nThreads<MAX_THREADS) /*Reads files from dir*/
    {

        if (temp->d_name[0] != '.')                     /*Ignores the ones beggining with '.'*/
        {   
            get_file_path(path, temp->d_name, file_path);   /*Computes rute (overwritten every iteration)*/
            printf("Got %s.\n", file_path);
            pthread_create(&thList[nThreads], NULL, reader_thread, (void * )file_path)  

            nThreads++; 
        }       
    }

    printf("readdir: %s\n", strerror (errno ));     /*Just in case*/

    for (i=0; i<nThreads ; i++)
        pthread_join(thList[i], NULL)

    if (file_path)
        free(file_path);

    return 0;

}

我的问题是,虽然路径计算得很好,但线程似乎没有收到正确的参数。他们都读取同一个文件。这是我得到的输出:

Got test/testB.
Got test/testA.
readdir: Success
Opened test/testA.
Thread 139976911939328 -> test/testA: 3536
Thread 139976911939328 -> test/testA: 37
Thread 139976911939328 -> test/testA: -38
Thread 139976911939328 -> test/testA: -985
Opened test/testA.
Thread 139976903546624 -> test/testA: 3536
Thread 139976903546624 -> test/testA: 37
Thread 139976903546624 -> test/testA: -38
Thread 139976903546624 -> test/testA: -985

如果我在下一个线程开始之前加入线程,它就可以正常工作。所以我假设某处有一个关键部分,但我真的不知道如何找到它。我试过互斥整个线程函数:

void * reader_thread (void * arg)
{   

    pthread_mutex_lock(&mutex_file);
    /*...*/
    pthread_mutex_unlock(&mutex_file);

}

另外,在第二个函数中互斥 while 循环。甚至两者同时。但它不会以任何方式工作。顺便说一句,mutex_file 是一个全局变量,由 main() 中的 pthread_mutex_init() 初始化。

我真的很感激你的建议,因为我真的不知道我做错了什么。我也希望有一些好的引用资料或书籍,因为互斥量和 System V 信号量对我来说有点难。

非常感谢。

最佳答案

好吧,您将与文件路径完全相同的指针传递给两个线程。结果,他们从同一个字符串中读取文件名并最终读取同一个文件。实际上,你在这里有点幸运,因为实际上你有一个竞争条件——你通过 file_path 更新字符串指针的内容,同时启动从该指针读取的线程,所以你可能最终线程在更改内存时读取该内存。您需要做的是分别为每个线程分配一个参数(即在您的 while 循环中调用 malloc 和相关逻辑),然后在线程退出后释放这些参数。

关于c - 如何让多个线程互不干扰地读取多个文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13315771/

相关文章:

java - 我是否需要在保证发生之前的对象上进行同步?

java - runOnUiThread 方法和 Handler 有什么区别?哪一个最好用?

c - 如何获取指向C中函数的函数指针?

c++ - 如何在Windows上为g++安装pthreads.h?

java - 线程安全地从集合中查找和删除对象

c++ - C - 使用 PThreads 时更快地锁定整数

c - 使用 malloc() 和 realloc() 将字符串存储在数组中

c - 给定的代码有什么问题

c - N叉树在c中的实现

C - 如何检查进程是否为系统进程?