Comment vérifier si un fichier est déjà ouvert dans C

Je travaille sur un système multithread dans lequel un fichier peut être partagé entre différents threads en fonction des permissions d’access aux fichiers. Comment puis-je vérifier si le fichier est déjà ouvert par un autre thread. Merci d’avance

Vous pouvez utiliser int flock (int fd, int operation); marquer un fichier comme verrouillé et également vérifier s’il est verrouillé.

  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 devrait fonctionner dans une application threadée si vous ouvrez le fichier séparément dans chaque thread: plusieurs threads capables d’obtenir un flock en même temps

Il y a plus d’informations sur le troupeau et ses faiblesses potentielles ici :

Pour savoir si un fichier nommé est déjà ouvert sur Linux , vous pouvez parsingr le /proc/self/fd pour voir si le fichier est associé à un descripteur de fichier. Le programme ci-dessous esquisse une 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; 

D’après votre commentaire, il semble que vous souhaitiez récupérer un FILE * existant déjà créé par un précédent appel à fopen() sur le fichier. La bibliothèque C standard ne fournit aucun mécanisme pour parcourir tous les FILE * actuellement ouverts. S’il existait un tel mécanisme, vous pourriez dériver son descripteur de fichier avec fileno() , puis interroger /proc/self/fd/# avec readlink() comme indiqué ci-dessus.

Cela signifie que vous devrez utiliser une structure de données pour gérer vos fichiers FILE * ouverts. Une table de hachage utilisant le nom de fichier comme clé serait probablement la plus utile pour vous.

Je ne connais pas beaucoup le multithreading sous Windows, mais vous avez beaucoup d’options si vous êtes sous Linux. Voici une ressource fantastique . Vous pouvez également tirer parti de toutes les fonctionnalités de locking de fichiers proposées de manière inhérente ou explicite par le système d’exploitation (ex: fcntl ). Plus d’informations sur les verrous Linux ici . Créer et gérer manuellement vos propres mutex vous offre plus de flexibilité que ce que vous auriez autrement. Le commentaire de user814064 propos de flock() ressemble à la solution parfaite, mais il n’est jamais mauvais d’avoir des options!

Ajout d’un exemple de code:

 #include  #include  #include  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; } 

Si vous avez tendance à le faire en shell, vous pouvez simplement utiliser lsof $filename .