我正在研究一个多线程系统,根据文件访问权限,可以在不同的线程之间共享文件。如何检查文件是否已被另一个线程打开。提前致谢
答案 0 :(得分:3)
您可以使用int flock(int fd, int operation);将文件标记为已锁定,并检查文件是否已锁定。
Apply or remove an advisory lock on the open file specified by fd.
The argument operation is one of the following:
LOCK_SH Place a shared lock. More than one process may hold a
shared lock for a given file at a given time.
LOCK_EX Place an exclusive lock. Only one process may hold an
exclusive lock for a given file at a given time.
LOCK_UN Remove an existing lock held by this process.
如果你在每个线程中单独打开文件,flock应该在一个线程应用程序中工作: multiple threads able to get flock at the same time
有关flock的更多信息及其潜在的弱点here:
答案 1 :(得分:2)
要查明linux上是否已打开命名文件,您可以扫描/proc/self/fd
目录以查看该文件是否与文件描述符相关联。下面的程序草拟了一个解决方案:
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()
调用创建了FILE *
。标准C库没有提供迭代所有当前打开的fileno()
的机制。如果有这样的机制,您可以使用/proc/self/fd/#
派生其文件描述符,然后使用readlink()
查询FILE *
,如上所示。
这意味着您需要使用数据结构来管理您的开放{{1}}。可能使用文件名作为键的哈希表对您来说最有用。
答案 2 :(得分:1)
我不太了解Windows上的多线程,但如果您使用的是Linux,那么您有很多选择。 Here 是 FANTASTIC 资源。您也可以利用任何file-locking features offered inherently or explicitly by the OS(例如:fcntl
)。有关Linux锁here的更多信息。创建和手动管理自己的互斥锁可以提供比原本更灵活的灵活性。 user814064
关于flock()
的评论看起来像是一个完美的解决方案,但是选择它绝对不会受到伤害!
添加了一个代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
FILE *fp;
int counter;
pthread_mutex_t fmutex = PTHREAD_MUTEX_INITIALIZER;
void *foo() {
// pthread_mutex_trylock() checks if the mutex is
// locked without blocking
//int busy = pthread_mutex_trylock(&fmutex);
// this blocks until the lock is released
pthread_mutex_lock(&fmutex);
fprintf(fp, "counter = %d\n", counter);
printf("counter = %d\n", counter);
counter++;
pthread_mutex_unlock(&fmutex);
}
int main() {
counter = 0;
fp = fopen("threads.txt", "w");
pthread_t thread1, thread2;
if (pthread_create(&thread1, NULL, &foo, NULL))
printf("Error creating thread 1");
if (pthread_create(&thread2, NULL, &foo, NULL))
printf("Error creating thread 2");
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
fclose(fp);
return 0;
}
答案 3 :(得分:0)
如果您倾向于在shell中执行此操作,则只需使用lsof $filename
。