温馨提示×

ubuntu readdir会阻塞吗

小樊
37
2026-10-12 11:05:26
栏目: 智能运维

在 Ubuntu(Linux) 上,readdir 本身是一个同步(阻塞)的系统调用封装,但是否“会阻塞”要看具体场景。


1. readdir 是什么

在 glibc 中:

  • readdir() / readdir_r() 是对 getdents() / getdents64() 系统调用的封装
  • 用于读取一个已打开目录中的目录项
DIR *dir = opendir("/path");
struct dirent *ent = readdir(dir);

2. readdir 会阻塞吗?

✅ 一般情况下:会“阻塞”(同步调用)

  • readdir 是 阻塞式 API
  • 如果内核需要从磁盘 / 网络文件系统读取目录数据:
    • 本地磁盘:通常很快,但仍可能短暂阻塞
    • 网络文件系统(NFS、SMB):可能明显阻塞
  • 调用线程会一直等到数据返回

✅ 但通常是“短阻塞”

  • 目录数据通常已缓存
  • 一次 readdir 不会读整个目录,而是分批
  • 对本地文件系统,延迟通常可忽略

3. 什么情况下 readdir 会“卡住”?

❗ 网络文件系统

  • NFS 超时
  • 服务器无响应
  • 挂载参数不合理(如 hard 挂载)

❗ 目录非常大

  • 百万级文件
  • 每次 readdir 触发大量 getdents

❗ 存储设备异常

  • 磁盘 I/O 卡死
  • RAID 降级

4. readdir vs readdir_r vs getdents

函数 是否阻塞 说明
readdir ✅ 阻塞 非线程安全
readdir_r ✅ 阻塞 线程安全
getdents64 ✅ 阻塞 系统调用
io_uring ❌ 可异步 新方式

5. 如何实现“非阻塞 readdir”?

✅ 方法 1:多线程

pthread_create(&t, NULL, scan_dir, path);

✅ 方法 2:异步 I/O(高级)

  • io_uring + getdents64
  • 目前较新,复杂度高

✅ 方法 3:避免主线程调用

  • 工作线程中 opendir/readdir
  • 主线程只做调度

6. 总结一句话

在 Ubuntu 上,readdir 是阻塞调用,但对本地文件系统通常很快;在 NFS 或异常存储下可能明显卡住。

如果你愿意,我可以:

  • 给你一个 不会卡 UI 的目录遍历示例
  • 或分析你遇到的 具体卡顿场景(NFS / Docker / 大目录)

0 踩