web-dev-qa-db-fra.com

fcntl, lockf, qui est préférable d'utiliser pour le verrouillage de fichiers?

Recherche d'informations concernant les avantages et inconvénients des deux fcntl et lockf pour le verrouillage des fichiers. Par exemple, lequel est préférable d'utiliser pour la portabilité? Je suis en train de coder un démon linux et je me demande lequel est le mieux adapté à l'utilisation pour appliquer l'exclusion mutuelle.

46
cweston

Quelle est la différence entre lockf et fcntl:

Sur de nombreux systèmes, la routine de bibliothèque lockf() n'est qu'un wrapper autour de fcntl(). C'est-à-dire que lockf offre un sous-ensemble des fonctionnalités que fcntl offre.

Source

Mais sur certains systèmes, les verrous fcntl et lockf sont complètement indépendants.

Source

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

Celui que vous avez choisi n'a pas d'importance.


Quelques remarques sur les verrous obligatoires vs consultatifs:

Le verrouillage sous unix/linux est par défaut consultatif , ce qui signifie que les autres processus n'ont pas besoin de suivre les règles de verrouillage définies. Peu importe la façon dont vous vous verrouillez, tant que vos processus de coopération utilisent également la même convention.

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

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

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


Fonctionnement des verrous obligatoires sous Linux:

Concernant les verrous obligatoires, si un processus verrouille une région d'un fichier avec un verrou de lecture, alors d'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 en écriture, les autres processus ne sont pas autorisés à lire ni à écrire dans le fichier. Ce qui se produit lorsqu'un processus n'est pas autorisé à accéder à la partie du fichier dépend de si vous avez spécifié O_NONBLOCK ou pas. Si le blocage est défini, il attendra pour effectuer l'opération. Si aucun blocage n'est défini, vous obtiendrez un code d'erreur de EAGAIN.


Avertissement NFS:

Soyez prudent si vous utilisez des commandes de verrouillage sur un montage NFS. Le comportement n'est pas défini et l'implémentation varie considérablement selon qu'il faut utiliser un verrou local uniquement ou prendre en charge le verrouillage à distance.

62
Brian R. Bondy

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

Un mot de prudence: il n'est pas spécifié ce qui se passe lorsqu'un processus verrouille un fichier à l'aide de fcntl et un autre à l'aide de 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 interopérez 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 des conseils: vous êtes responsable de vérifier si une région est verrouillée. N'utilisez pas non plus les fonctions stdio si vous souhaitez utiliser la fonction de verrouillage.

10
Diomidis Spinellis

Vos principales préoccupations, dans ce cas (c'est-à-dire quand " coder un démon Linux et se demander lequel est le mieux adapté à utiliser pour appliquer 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 inciter à créer et à verrouiller le fichier pid de votre démon sur NFS?
  2. comment le verrou se comportera-t-il lorsque forking, ou lorsque le processus démon se terminera avec un préjudice extrême, par exemple kill -9?

Les commandes flock et fcntl se comportent différemment dans les deux cas.

Ma recommandation serait d'utiliser fcntl. Vous pouvez vous référer à article sur le verrouillage de 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 déroutent parfois les programmeurs d'autres systèmes d'exploitation. Le fonctionnement des verrous flock sur les systèmes de fichiers réseau, tels que NFS, dépend de l'implémentation. Sur les systèmes BSD, les appels de troupeau sont des no-ops réussis. Sous Linux avant 2.6.12, les appels de troupeau sur les fichiers NFS n'agissaient que localement. Le noyau 2.6.12 et les versions ultérieures implémentent des appels de troupeau sur les fichiers NFS à l'aide de verrous de plage d'octets POSIX. Ces verrous seront visibles pour les autres clients NFS qui implémentent des verrous fcntl ()/POSIX . 1 Les mises à niveau et rétrogradations de verrou libèrent l'ancien verrou avant d'appliquer le nouveau verrou. Si une application rétrograde un verrou exclusif en verrou partagé tandis qu'une autre application est bloquée en attendant un verrou exclusif, cette dernière application obtiendra le verrou exclusif et la première application sera verrouillée. Tous les verrous fcntl associés à un fichier pour un processus donné sont supprimés lorsqu'un descripteur de fichier pour ce fichier est fermé par ce processus, même si un verrou n'a jamais été demandé pour ce descripteur de fichier. De plus, les verrous fcntl ne sont pas hérités par un processus enfant. La sémantique de fermeture fcntl est particulièrement gênante pour les applications qui appellent des bibliothèques de sous-programmes pouvant accéder aux fichiers.

9
vladr

Je suis tombé sur un problème lors de l'utilisation de fcntl et flock récemment que je pensais que je devrais signaler ici car la recherche de l'un ou l'autre terme montre cette page en haut des deux.

Notez que les verrous BSD, comme mentionné ci-dessus, sont consultatif. Pour ceux qui ne connaissent pas OSX (darwin) c'est BSD. Il faut s'en souvenir lors de l'ouverture d'un fichier dans lequel é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 mis à zéro. Si votre processus ne parvient pas à obtenir le verrou car le fichier est utilisé ailleurs, il reviendra très probablement, laissant le fichier à 0 Ko. Le processus qui avait le verrou trouvera maintenant que le fichier a disparu en dessous, des résultats catastrophiques suivent normalement.

Pour remédier à cette situation, lors de l'utilisation du verrouillage de fichier, jamais ouvrez le fichier "w", mais ouvrez-le plutôt "a", pour l'ajouter. Ensuite, si le verrou est acquis avec succès, vous pouvez ensuite effacer le fichier en toute sécurité comme "w" l'aurait fait, c'est-à-dire. :

fseek (fileHandle, 0, SEEK_SET); // passe au début

ftruncate (fileno ((FILE *) fileHandle), 0); // efface-le

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

7
RMCE

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 que d'être compatible avec elle-même.

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

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

1
MarkR