如何检查文件是否已经在C中打开

问题描述:

我正在开发一个多线程系统,其中可以根据文件访问权限在不同线程之间共享文件.

I am working on a multithreaded system where a file can be shared among different threads based on the file access permissions.

如何检查文件是否已被另一个线程打开?

How can I check if file is already opened by another thread?

了解是否已在的问题,您可以扫描/proc/self/fd 目录以查看该文件是否与文件描述符关联.下面的程序概述了一个解决方案:

To find out if a named file is already opened on linux, you can scan the /proc/self/fd directory to see if the file is associated with a file descriptor. The program below sketches out a solution:

DIR *d = opendir("/proc/self/fd");
if (d) {
    struct dirent *entry;
    struct dirent *result;

    entry = malloc(sizeof(struct dirent) + NAME_MAX + 1);
    result = 0;
    while (readdir_r(d, entry, &result) == 0) {
        if (result == 0) break;
        if (isdigit(result->d_name[0])) {
            char path[NAME_MAX+1];
            char buf[NAME_MAX+1];
            snprintf(path, sizeof(path), "/proc/self/fd/%s",
                     result->d_name);
            ssize_t bytes = readlink(path, buf, sizeof(buf));
            buf[bytes] = '\0';
            if (strcmp(file_of_interest, buf) == 0) break;
        }
    }
    free(entry);
    closedir(d);
    if (result) return FILE_IS_FOUND;
}
return FILE_IS_NOT_FOUND;

根据您的评论,似乎您想要做的就是检索现有的 FILE * (如果先前通过调用 fopen()创建了一个文件)文件.标准C库没有提供机制来遍历所有当前打开的 FILE * .如果存在这种机制,则可以使用 fileno()导出其文件描述符,然后使用 readlink()查询/proc/self/fd/#,如上所示.

From your comment, it seems what you want to do is to retrieve an existing FILE * if one has already been created by a previous call to fopen() on the file. There is no mechanism provided by the standard C library to iterate through all currently opened FILE *. If there was such a mechanism, you could derive its file descriptor with fileno(), and then query /proc/self/fd/# with readlink() as shown above.

这意味着您将需要使用数据结构来管理打开的 FILE * .使用文件名作为键的哈希表可能对您最有用.

This means you will need to use a data structure to manage your open FILE *s. Probably a hash table using the file name as the key would be the most useful for you.