温馨提示×

ubuntu readdir如何中断

小樊
49
2026-10-12 11:23:28
栏目: 智能运维

在 Ubuntu / Linux 下,readdir()(或 readdir_r())本身没有“中断”参数,它只是顺序读取目录项。如果你说的“中断”是指:

在读取目录过程中,主动停止 / 取消 / 超时退出

常见做法有以下几种:


一、在应用层自己“中断”(最常用)

1️⃣ 用标志位(信号 / 线程控制)

volatile sig_atomic_t stop = 0;

void handler(int sig) {
    stop = 1;
}

DIR *dir = opendir("/path");
struct dirent *entry;

while ((entry = readdir(dir)) != NULL) {
    if (stop) {
        printf("interrupted\n");
        break;
    }
    printf("%s\n", entry->d_name);
}
closedir(dir);

配合:

signal(SIGINT, handler);

✅ 适合:

  • Ctrl+C
  • 超时
  • 用户取消

二、使用 alarm() 超时中断(不推荐但可用)

#include <unistd.h>
#include <signal.h>

void timeout(int sig) {
    // 什么都不做,只是打断系统调用
}

signal(SIGALRM, timeout);
alarm(2); // 2 秒

readdir(dir); // 超时后返回 EINTR

⚠️ 注意:

  • readdir() 不是异步信号安全函数
  • 现代程序更推荐 timerfd 或 select/poll

三、改为非阻塞 + select() / epoll(高级)

目录本身不能直接 select(),但可以:

  • 用 worker 线程 + 管道
  • 主线程向管道写 1 字节 → 子线程退出

示例思路:

主线程 ---> pipe ---> 工作线程(readdir)

工作线程:

if (read(pipe_fd, &c, 1) > 0) break;

✅ 适合:

  • 长目录
  • 网络服务
  • GUI 程序

四、用 getdents() 替代(底层)

readdir() 是 libc 封装,底层是:

syscall(SYS_getdents64, fd, buf, size);

仍然不能中断,只能靠:

  • 自己控制循环
  • 提前 close(fd)

五、多线程中“强制中断”(不推荐)

❌ 不要:

  • pthread_cancel()
  • 强制杀线程

会导致:

  • 资源泄漏
  • 目录锁未释放

✅ 推荐方案总结

场景 推荐方式
普通程序 signal + 标志位
超时 alarm / timerfd
服务程序 线程 + pipe
GUI 事件循环 + 取消标志

如果你能说明:

  • 是 C / C++ / Python / Shell
  • 是 超大目录 还是 普通目录
  • 想要 Ctrl+C / 超时 / 用户取消

我可以给你具体可运行代码。

0 踩