48 votes

fcntl, lockf, lequel est le meilleur à utiliser pour le verrouillage des fichiers ?

Vous cherchez des informations concernant le avantages y inconvénients des deux fcntl y lockf pour le verrouillage des fichiers. Par exemple, quelle est la meilleure solution pour la portabilité ? Je suis en train de coder un démon linux et je me demande lequel est le mieux adapté à l'application de l'exclusion mutuelle.

63voto

Brian R. Bondy Points 141769

Quelle est la différence entre lockf et fcntl :

Sur de nombreux systèmes, le lockf() est juste une enveloppe autour de fcntl() . C'est-à-dire lockf offre un sous-ensemble de la fonctionnalité que fcntl fait.

Source :

Mais sur certains systèmes, fcntl y lockf Les serrures sont totalement indépendantes.

Source :

Comme cela dépend de l'implémentation, veillez à toujours utiliser la même convention. Donc, soit vous utilisez toujours lockf dans vos deux processus, soit vous utilisez toujours fcntl. Il y a de fortes chances qu'ils soient interchangeables, mais il est plus sûr d'utiliser la même convention.

Lequel vous avez choisi n'a pas d'importance.


Quelques remarques sur les verrous obligatoires ou consultatifs :

Le verrouillage dans unix/linux est par défaut conseil Ce qui signifie que les autres processus n'ont pas besoin de suivre les règles de verrouillage qui sont définies. Ainsi, la façon dont vous verrouillez n'a pas d'importance, tant que les processus qui coopèrent avec vous utilisent la même convention.

Linux prend en charge obligatoire mais seulement si votre système de fichiers est monté avec l'option activée et les attributs spéciaux du fichier définis. Vous pouvez utiliser mount -o mand pour monter le système de fichiers et définir les attributs des fichiers g-x,g+s pour activer les verrous obligatoires, puis utilisez fcntl o lockf . Pour plus d'informations sur le fonctionnement des verrous obligatoires, voir aquí .

Notez que les verrous ne sont pas appliqués au fichier individuel, mais à l'inode. Cela signifie que deux noms de fichiers qui pointent vers les mêmes données partageront le même état de verrouillage.

Dans Windows, en revanche, vous pouvez ouvrir un fichier de manière active et exclusive, ce qui empêchera les autres processus de l'ouvrir complètement. Même s'ils le veulent. C'est-à-dire que les verrous sont obligatoires. Il en va de même pour Windows et les verrous de fichiers. Tout processus ayant un handle de fichier ouvert avec un accès approprié peut verrouiller une partie du fichier et aucun autre processus ne pourra accéder à cette partie.


Comment les verrous obligatoires fonctionnent sous Linux :

Concernant les verrous obligatoires, si un processus verrouille une région d'un fichier avec un verrou de lecture, les autres processus sont autorisés à lire mais pas à écrire dans cette région. Si un processus verrouille une région d'un fichier avec un verrou d'écriture, les autres processus ne sont pas autorisés à lire ou à écrire dans le fichier. Ce qui se passe lorsqu'un processus n'est pas autorisé à accéder à la partie du fichier dépend du fait que vous ayez spécifié ou non l'option O_NONBLOCK ou non. Si le blocage est activé, il attendra pour effectuer l'opération. Si aucun blocage n'est défini, vous obtiendrez le code d'erreur suivant EAGAIN .


Avertissement NFS :

Faites attention si vous utilisez des commandes de verrouillage sur un montage NFS. Le comportement n'est pas défini et l'implémentation varie largement entre l'utilisation d'un verrouillage local uniquement et la prise en charge du verrouillage à distance.

3 votes

Ce n'est plus correct. Le verrouillage des fichiers fonctionne sur nfs 3.0, mais seulement avec fcntl, pas flock.

8 votes

"Mais sur certains systèmes, les verrous fcntl et lockf sont complètement indépendants" -- Non. Sur certains systèmes, les verrous fcntl et flock sont complètement indépendants, comme l'explique l'article auquel vous avez fait référence. Cependant, les verrous fcntl et lockf sont toujours liés (mais pas à flock).

10voto

Diomidis Spinellis Points 8417

Les deux interfaces font partie de la norme POSIX, et de nos jours, les deux interfaces sont disponibles sur la plupart des systèmes (je viens de vérifier sur Linux, FreeBSD, Mac OS X et Solaris). Par conséquent, choisissez celle qui correspond le mieux à vos besoins et utilisez-la.

Un mot d'avertissement : il n'est pas spécifié ce qui se passe lorsqu'un processus verrouille un fichier en utilisant fcntl et un autre en utilisant lockf. Dans la plupart des systèmes, ce sont des opérations équivalentes (en fait, sous Linux, lockf est implémenté au-dessus de fcntl), mais POSIX dit que leur interaction n'est pas spécifiée. Donc, si vous interagissez avec un autre processus qui utilise l'une des deux interfaces, choisissez la même.

D'autres ont écrit que les verrous ne sont que consultatifs : vous êtes responsable de vérifier si une région est verrouillée. De plus, n'utilisez pas les fonctions stdio, si vous voulez utiliser la fonctionnalité de verrouillage.

9voto

vladr Points 34562

Vos principales préoccupations, dans ce cas (c'est-à-dire lorsque " codage d'un démon Linux et je me demande lequel est le mieux adapté à l'utilisation pour l'application de l'exclusion mutuelle "), devrait être :

  1. Le fichier verrouillé sera-t-il local ou peut-il être sur NFS ?
    • Par exemple, l'utilisateur peut-il vous piéger en créant et verrouillant le fichier pid de votre démon sur NFS ?
  2. comment la serrure se comportera-t-elle lorsque fork ou lorsque le processus du démon est interrompu de manière extrêmement préjudiciable, par exemple. kill -9 ?

El flock y fcntl se comportent différemment dans les deux cas.

Je recommande d'utiliser fcntl . Vous pouvez vous référer à la Article sur le verrouillage des fichiers sur Wikipedia pour une discussion approfondie des problèmes liés aux deux solutions :

flock et fcntl ont tous les deux des bizarreries qui occasionnellement les programmeurs d'autres d'autres systèmes d'exploitation. Que les verrous flock fonctionne sur les systèmes de fichiers en réseau, comme NFS, dépend de l'implémentation dépend de l'implémentation. Sur les systèmes BSD, les appels flock sont des no-ops réussis. Sur les systèmes Linux antérieurs à 2.6.12, les appels flock sur des fichiers NFS n'agissaient que localement. Les noyaux 2.6.12 et supérieur implémentent les appels flock sur les fichiers NFS en utilisant des verrous POSIX de plage d'octets. Ces verrous seront visibles pour les autres clients NFS qui implémentent fcntl()/verrous POSIX. 1 Les mises à niveau des serrures et les déclassements libèrent l'ancien verrou avant d'appliquer le nouveau verrou. Si une application rétrograde un verrou exclusif en verrou partagé alors qu'une autre application est bloquée en attente d'un verrou exclusif, cette dernière application obtiendra le verrou exclusif et la exclusive et la première application sera bloquée. Tous les verrous fcntl associés à un fichier pour un processus donné sont supprimés lorsque tout descripteur de fichier pour ce fichier est fichier est fermé par ce processus, même si un verrou n'a jamais été demandé pour ce descripteur ce descripteur de fichier. De même, les verrous fcntl ne sont pas hérités par un processus enfant. Le site sémantique de fermeture fcntl est particulièrement particulièrement gênante pour les applications qui appellent des bibliothèques de sous-routines qui peuvent accéder à des fichiers.

8voto

RMCE Points 81

J'ai rencontré un problème lors de l'utilisation de fcntl et flock récemment et j'ai pensé que je devais le signaler ici, car la recherche de l'un ou l'autre terme montre cette page en haut de la page sur les deux.

Sachez que les verrous BSD, comme mentionné ci-dessus, sont conseil . Pour ceux qui ne le savent pas, OSX (darwin) est BSD. Il faut s'en souvenir quand on ouvre un fichier pour y écrire.

Pour utiliser fcntl/flock, vous devez d'abord ouvrir le fichier et obtenir son ID. Cependant si vous avez ouvert le fichier avec "w" le fichier sera instantanément réduit à zéro . Si votre processus ne parvient pas à obtenir le verrou parce que le fichier est utilisé ailleurs, il reviendra très probablement, laissant le fichier à 0 kb. Le processus qui avait le verrou découvrira alors que le fichier a disparu, ce qui entraîne normalement des résultats catastrophiques.

Pour remédier à cette situation, lorsque vous utilisez le verrouillage des fichiers, jamais ouvrir le fichier "w", mais à la place ouvrir "a", pour ajouter. Ensuite, si le verrou est acquis avec succès, vous pouvez alors effacer le fichier comme "w" l'aurait fait, c'est-à-dire :

fseek(fileHandle, 0, SEEK_SET);//déplacement vers le départ

ftruncate(fileno((FILE *) fileHandle), 0);//effacer le tout

Ce fut une leçon désagréable pour moi.

2 votes

Je suppose que vous vouliez dire ouvrir le fichier avec "r+" (O_RDWR) plutôt que "a" (O_APPEND) -- et évidemment sans O_TRUNC comme "w" ferait

1voto

MarkR Points 37178

Comme vous ne codez qu'un démon qui l'utilise pour l'exclusion mutuelle, ils sont équivalents, après tout, votre application n'a besoin d'être compatible qu'avec elle-même.

L'astuce avec les mécanismes de verrouillage des fichiers est d'être cohérent - utilisez-en un et tenez-vous en à ce dernier. Les faire varier est une mauvaise idée.

Je suppose ici que le système de fichiers sera un système local - si ce n'est pas le cas, alors tous les paris sont ouverts, NFS / d'autres systèmes de fichiers réseau gèrent le verrouillage avec des degrés variables d'efficacité (dans certains cas aucun)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X