在 Debian(以及一般 Linux)下,“readdir 如何加锁”通常有两种理解,下面分别说明。
readdir() 只是读目录项,POSIX 没有“读目录锁”。
常见做法是使用 文件锁(fcntl / flock) 或 自定义锁文件。
#include <sys/file.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
int main() {
int dfd = open("/path/to/dir", O_RDONLY);
flock(dfd, LOCK_SH); // 共享锁(读)
// 或 LOCK_EX 独占锁(写)
DIR *dir = opendir("/path/to/dir");
struct dirent *de;
while ((de = readdir(dir))) {
// 处理目录项
}
closedir(dir);
flock(dfd, LOCK_UN);
close(dfd);
return 0;
}
✅ 优点:简单
⚠ 注意:
flock 不跨 NFSstruct flock fl = {
.l_type = F_RDLCK,
.l_whence = SEEK_SET,
.l_start = 0,
.l_len = 0
};
fcntl(dfd, F_SETLKW, &fl);
如果你在多线程程序里调用 readdir(),那就必须加线程锁。
readdir() 不是线程安全
✅ 应使用 readdir_r() 或 readdir_r + mutex
#include <pthread.h>
#include <dirent.h>
pthread_mutex_t dir_lock = PTHREAD_MUTEX_INITIALIZER;
DIR *dir;
void *worker(void *) {
struct dirent *de;
pthread_mutex_lock(&dir_lock);
while ((de = readdir(dir))) {
// 处理 de
}
pthread_mutex_unlock(&dir_lock);
return NULL;
}
Debian 新版本 glibc 中
readdir()实际已是线程局部状态,但多线程共享同一个 DIR* 仍然不安全
❌ 不存在
O_LOCKDIR只能:
| 误区 | 说明 |
|---|---|
| readdir 自动加锁 | ❌ |
| 锁目录能阻止 rm | ❌ |
| flock 文件能锁目录内容 | ❌(只锁“锁本身”) |
flock(dir_fd, LOCK_SH/EX)pthread_mutex + readdir如果你能说明:
我可以给你更精确的方案。