温馨提示×

centos readdir如何并发

小樊
46
2026-09-12 01:43:16
栏目: 智能运维

在 CentOS(Linux) 上,如果你说的 readdir 是指 遍历目录(readdir / readdir_r / getdents),想并发地读取多个目录或并发处理目录项,可以从下面几个层面来做:


一、先明确:readdir 本身不支持“并发读同一个目录”

  • readdir() / readdir_r() 不是线程安全的(readdir 本身有内部状态)
  • 同一个 DIR* 不能在多个线程中并发调用
  • 但你可以:
    • ✅ 多个线程 各自打开不同目录
    • ✅ 单线程 readdir,多线程处理结果
    • ✅ 多个线程分别 readdir 不同子目录

二、推荐做法 1:多线程分别 readdir 不同目录(最常见)

示例(C + pthread)

#include <dirent.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>

void* scan_dir(void* arg) {
    char* path = arg;
    DIR* dir = opendir(path);
    if (!dir) return NULL;

    struct dirent* entry;
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_name[0] == '.') continue;
        printf("%s/%s\n", path, entry->d_name);
    }
    closedir(dir);
    return NULL;
}

int main() {
    pthread_t t1, t2;
    pthread_create(&t1, NULL, scan_dir, "/var/log");
    pthread_create(&t2, NULL, scan_dir, "/tmp");

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    return 0;
}

✅ 安全、简单、高效


三、推荐做法 2:单线程 readdir + 线程池处理(更优)

适合:

  • 目录项很多
  • 处理每个文件很慢(IO / 计算)

思路

  1. 主线程 readdir
  2. 把 d_name 扔进队列
  3. 工作线程处理
readdir → queue → worker threads

伪代码

while ((e = readdir(dir))) {
    push_queue(e->d_name);
}

四、推荐做法 3:并发遍历目录树(递归目录)

策略

  • 发现子目录 → 创建新线程 / 提交任务
  • 控制最大线程数(线程池)
/
├── a/  → thread1
├── b/  → thread2
├── c/  → thread3

⚠️ 注意:

  • 不要无限制创建线程
  • 推荐用 pthread_pool 或 libuv / libevent

五、系统调用层:getdents(更快)

readdir 底层是 getdents64

#include <sys/syscall.h>
#include <unistd.h>

✅ 性能更好
❌ 可移植性差
✅ 仍 不能并发读同一目录


六、CentOS 上的高级方案

1️⃣ io_uring(CentOS 8+ / Stream 9)

  • 支持异步目录遍历
  • 性能极高
  • 复杂度高

2️⃣ parallel find(现成工具)

find /path -type f | xargs -P 8 -I{} process {}

七、总结建议

场景 推荐方案
多目录 多线程各自 readdir
单目录很多文件 单线程 readdir + 线程池
目录树 递归 + 线程池
极致性能 io_uring

如果你愿意,可以告诉我:

  • 用 C / C++ / Python / Shell?
  • 是 单目录 还是 整棵目录树?
  • 是 读文件名 还是 读文件内容?

我可以直接给你一份可编译的并发 readdir 示例。

0 踩