温馨提示×

ubuntu readdir是否线程安全

小樊
41
2026-09-21 20:40:05
栏目: 智能运维

Ubuntu(Linux) 上,readdir 的线程安全性要分情况说,不能简单回答“安全”或“不安全”。


1. readdir(POSIX 标准,glibc 实现)

函数原型:

struct dirent *readdir(DIR *dirp);

结论

readdir 本身不是线程安全的

原因:

  • readdir 返回的 struct dirent *指向内部静态缓冲区 的指针
  • 同一个 DIR * 流在多线程中 共享该缓冲区
  • 如果多个线程 同时使用同一个 DIR * 调用 readdir,会发生数据竞争

不安全示例(错误)

// 两个线程同时用同一个 dir 调用 readdir
readdir(dir);  // ❌ 不安全

2. 如何安全地使用 readdir

✅ 方法一:加锁(互斥量)

pthread_mutex_lock(&lock);
struct dirent *ent = readdir(dir);
pthread_mutex_unlock(&lock);

适用于:多个线程共享同一个目录流。


✅ 方法二:每个线程使用独立的 DIR *

DIR *dir = opendir(path);

不同线程 opendir 不同或各自打开,互不干扰。


✅ 方法三:使用线程安全版本 readdir_r(已不推荐)

int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

⚠️ 注意:

  • readdir_rglibc 2.34+ 已被废弃
  • POSIX.1-2024 已移除
  • 官方建议用 readdir + 锁 或 getline/openat 等替代

3. readdir 的“局部安全”说明

以下情况是安全的:

  • ✅ 多个线程 各自使用不同的 DIR *
  • ✅ 同一线程顺序调用 readdir
  • ❌ 多线程共享同一 DIR * 且无同步

4. 现代推荐做法(Ubuntu 20.04 / 22.04 / 24.04)

  • 单线程遍历:直接用 readdir
  • 多线程遍历
    • 每线程 opendir
    • 或加 pthread_mutex
  • 新项目可考虑:
    • openat + getdents64
    • C++ std::filesystem

总结一句话

Ubuntu 上的 readdir 不是线程安全的,但只要不同线程不共享同一个 DIR *,或加锁保护,就是安全的。

如果你愿意,我可以:

  • 给你一个 线程安全的目录遍历示例
  • 或对比 readdir vs std::filesystem::directory_iterator

0