Question

Voici le problème: j'ai deux applications, écrites en C ++ et qui s'exécutent sur deux ordinateurs dotés de systèmes d'exploitation différents (un Linux et un Windows). L'un de ces processus est chargé de mettre à jour un fichier XML sur un NAS (stockage associé au réseau), tandis que l'autre lit ce fichier.

Est-il possible de synchroniser ces deux processus afin d'éviter de lire le fichier en même temps qu'il est modifié?

Était-ce utile?

La solution

Vous pouvez créer un fichier de verrouillage sur le serveur créé avant d'écrire, attendre, puis écrire et supprimer à la fin., Demandez au processus de lecture de vérifier le jeton avant de lire le fichier.

Modifier : pour adresser les commentaires, vous pouvez implémenter un modèle de type de verrouillage vérifié. Demandez au lecteur et à l'écrivain d'avoir un fichier de verrouillage et une double vérification avant de commencer, quelque chose comme:

Lecteur: recherchez le fichier de verrouillage en écriture, créez un fichier de verrouillage en lecture, recherchez le fichier de verrouillage en écriture, le cas échéant, supprimez le fichier en lecture et annulez.

Writer: vérifie le fichier verrouillé en lecture, crée un fichier verrouillé en écriture, vérifie le fichier verrouillé en lecture, le cas échéant, supprime le fichier verrouillé en écriture et abandonne la tâche.

Ceci empêchera vos processus de se piétiner les uns les autres, mais une situation critique peut se produire: vous pouvez éventuellement faire vérifier, créer, revérifier simultanément les deux processus, même si cela ne provoque pas une lecture incohérente des données, mais provoquer l'abandon des processus de lecture et d'écriture pendant le délai spécifié

Autres conseils

Merci à tous pour vos réponses.

Enfin, nous avons réussi à résoudre notre problème, non pas en utilisant des commandes de verrouillage du système d'exploitation (car nous n'étions pas sûrs qu'elles se propageraient correctement vers le système d'exploitation de la tête NAS), mais en créant des répertoires de verrouillage au lieu de fichiers de verrouillage. La création de répertoire est une opération atomique et renvoie une valeur d'erreur si le dossier existe déjà. Par conséquent, il n'est pas nécessaire de vérifier l'existence du verrou avant de l'acquérir, les deux opérations sont effectuées en une seule étape.

OK, vous avez besoin d’un mécanisme de verrouillage pour contrôler les accès.

La plupart des systèmes de fichiers * nix fournissent cela. Je soupçonne qu'il est également disponible sur le système de fichiers Windows (car ce mécanisme est utilisé par perl), mais il peut avoir un autre nom.

Regardez le troupeau ().
Ceci est un mécanisme de verrouillage de fichier. Il s’agit d’un verrou consultatif qui ne verrouille pas le fichier et n’en empêche pas l’utilisation, mais fournit un mécanisme de marquage du fichier. Si les deux applications utilisent le mécanisme, vous pouvez contrôler les accès au fichier.

flock () fournit à la fois des verrous partagés (ou READ Lock) et des verrous exclusifs (ou WRITE Lock). flock bloquera votre thread (de manière non occupée) jusqu'à ce que le fichier soit déverrouillé par l'utilisateur (il fournit également des vérifications NON bloquantes afin que vous puissiez faire autre chose en attendant).

Consultez le groupe dans la section 2 des pages de manuel.

int     flock(int fd, int operation);

Flock() applies or removes an advisory lock on the file associated with the file
descriptor fd.  A lock is applied by specifying an operation parameter that is
one of LOCK_SH or LOCK_EX with the optional addition of LOCK_NB.  To unlock an
existing lock operation should be LOCK_UN.

Si les fichiers résident sur un partage NFS, vous pouvez utiliser fcntl (2) verrouiller le fichier. Consultez la question D10 dans la FAQ Linux NFS . J'ai très peu d'expérience avec les API Windows, mais d'après ce que j'ai entendu dire, ils ont un bon support POSIX. Vous devriez donc pouvoir utiliser fcntl tant qu'ils supportent POSIX.1-2001.

Si vous accédez aux fichiers en utilisant différents protocoles (par exemple, AFS ou SMB), vous pourriez peut-être configurer un serveur de synchronisation simple qui gère les verrous via une interface IPC?

Serait-il possible de passer de fichiers à une base de données?

Ce type de concurence est quelque chose que les SGBD gèrent très bien. Il ne doit pas être cher ou difficile à installer. MySql, Postgress ou JavaDB traiteraient cela avec élégance à peu de frais, voire aucun.

Si l'option de base de données échouait, le processus d'écriture serait écrit dans un fichier "masqué". nom de fichier tel que " .updateinprogress.xml " et renommez le fichier lorsque la mise à jour est terminée. Sur la plupart des systèmes " mv " ou " ren " est une opération atomique, le processus de lecture récupère soit le fichier ancien, soit le fichier le plus récent, mais jamais un fichier demi-écrit.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top