首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么readdir不是多线程安全的?

问为什么readdir不是多线程安全的?
EN

Stack Overflow用户
提问于 2022-09-07 07:28:33
回答 2查看 121关注 0票数 2

谢谢阅读这个问题,我只有基本的C知识,对linux系统不熟悉。以下是我对readdir的了解:

  1. 有人说readdir()不是多线程安全的信标,因为它使用了静态变量,因此readdir可以被描述为

代码语言:javascript
复制
    struct dirent* readdir() {
     static struct dirent; //read action 
     return &dirent;
    }

然而,使用readdir()对不同的目录流(即DIR结构)使用readdir()时,实际的glibc实现是多线程安全的,但当您读取自glibc 2.24以来推荐的同样的DIR流(https://lwn.net/Articles/696474/)

  • readdir_r时,就不安全了。原因如下

https://man7.org/linux/man-pages/man3/readdir_r.3.html

我的问题是:

  1. i在glibc源代码中没有看到任何静态变量,静态变量在哪里?

这是我读过的源代码。我只能看到它使用锁来确保多线程的安全。

https://github.com/lattera/glibc/blob/master/sysdeps/posix/readdir.c

  • I尝试使用多线程读取相同的目录流,如:

DIR* des_dir=opendir(xxx);

pthread_create(pid,0,custom_readdir,des_dir);

每个线程共享相同的目录流,结果是可以的。每个线程正确地输出目录的一部分,那么如何理解“在多个线程从同一个目录流中读取不安全的情况下?”

  • (如果readdir()确实不安全),如何安全地读取目录?我没有找到可以替换readdir().

的函数。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-07 09:34:35

我没有在glibc源代码中看到任何静态变量,静态变量在哪里?

没有静态变量。您所指向的代码使用目录流中的缓冲区来保存和返回struct dirent对象。因此,使用同一个目录流的多个线程是不安全的,因为它们可能在使用单个缓冲区时发生冲突。

我尝试使用多线程读取相同的目录流,例如: DIR* des_dir=opendir(xxx);pthread_create(pid,0,custom_readdir,des_dir);每个线程共享相同的目录流,结果是可以的。每个线程正确地输出目录的一部分,…

你在实验中运气不好,线程的执行碰巧发生了冲突。所使用的缓冲区确实为多个struct dirent提供了空间,允许多个线程使用不同的部分,这降低了观察故障的可能性,特别是当只使用几个目录进行测试时。

如果readdir()确实不安全,如何以安全的方式读取目录?

为每个线程打开一个单独的目录流。或者使用一个线程读取目录流,并让它复制所需的目录信息,并将其传递给其他线程来完成目录的工作。

票数 3
EN

Stack Overflow用户

发布于 2022-09-07 18:09:44

如果readdir()确实不安全,如何以安全的方式读取目录?

在所有POSIXy系统中,您可以使用scandir()、scandirat()、glob()和nftw()。nftw()是遍历整个目录树(查找特定文件)、扫描单个目录的scandir()/scandirat()的最佳选择。

其中,scandir()和scandirat()是线程安全的;nftw()是线程安全的,但wrt除外。遍历期间的当前工作目录。

在Linux中,您还可以使用函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73631601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档