Question

S'il vous plaît noter que ce n'est pas en double de fichier r / w verrouillage et unlink. . (La différence -. Plate-forme des opérations de fichiers comme le verrouillage et la suppression ont une sémantique totalement différentes, ainsi le sultion serait différent)

Je le problème suivant. Je veux créer un stockage de session basé sur le système de fichiers où chaque données de session sont stockées dans simple fichier nommé avec ids de session.

Je veux API suivante: write(sid,data,timeout), read(sid,data,timeout), remove(sid) où le nom du fichier sid ==, je veux aussi avoir une sorte de GC qui peuvent enlever toutes les sessions délai d'attente dépassé.

tâche très simple si vous travaillez avec le processus unique, mais pas trivial absolutly lorsque vous travaillez avec plusieurs processus ou même sur des dossiers partagés.

La solution la plus simple que je pensais était:

write/read:
   hanlde=CreateFile
   LockFile(handle)
   read/write data
   UnlockFile(handle)
   CloseHanlde(handle)

GC (for each file in directory)
   hanlde=CreateFile
   LockFile(handle)
   check if timeout occured
     DeleteFile
   UnlockFile(handle)
   CloseHanlde(handle)

Mais je ne peux pas appeler AFIAK DeleteFile le fichier verrouillé opended (contrairement à Unix où le verrouillage des fichiers est pas obligatoire et unlink est autorisé pour les fichiers ouverts.

Mais si je mets DeleteFile en dehors du mauvais scénario boucle de verrouillage peut se produire

GC - CreateFile/LockFile/Unlock/CloseHandle,
write - oCreateFile/LockFile/WriteUpdatedData/Unlock/CloseHandle
GC - DeleteFile

Est-ce que quelqu'un a une idée de comment cette question peut être résolue? Y a-t-il des astuces qui permettent combiner le verrouillage de fichiers et la suppression ou faire l'opération sur le fichier atomique (Win32)?

Notes:

  • Je ne veux pas utiliser la base de données,
  • Je cherche une solution pour Win32 API pour NT 5.01 et au-dessus

Merci.

Était-ce utile?

La solution

Je ne comprends pas vraiment comment cela est censé fonctionner. Cependant, la suppression d'un fichier qui est ouvert par un autre processus est possible. Le processus qui crée le fichier doit utiliser le drapeau FILE_SHARE_DELETE pour l'argument dwShareMode de CreateFile (). Un appel ultérieur DeleteFile () réussira. Le fichier ne soit pas réellement supprimé du système de fichiers jusqu'à ce que la dernière poignée est fermée.

Autres conseils

Vous avez actuellement des données dans le dossier qui permet au GC de déterminer si l'enregistrement est expiré. Que diriez-vous étendre cette information d'entretien avec un drapeau « TooLateWeAlreadyTimedItOut ».

 GC sets TooLateWeAlreadyTimedItOut = true
 Release lock
    <== writer comes in here, sees the "TooLate" flag and so does not write
 GC deletes

En d'autres termes, nous utilisons une sorte d'approche de verrouillage optimiste. Cela exige une certaine complexité supplémentaire dans l'écrivain, mais maintenant vous n'êtes pas dépendant de rides OS spécifques.

Je ne comprends pas ce qui se passe dans le cas:

 GC checks timeout
 GC deletes
 Writer attempts write, and finds no file ...

Tout ce que vous avez prévu pour ce cas peut également être utilisé dans le cas « toolate »

Edité pour ajouter:

Vous avez dit qu'il est valide pour cette séquence se produire:

 GC Deletes
 (Very slightly later) Writer attempts a write, sees no file, creates a new one

L'auteur peut traiter le drapeau « toolate » comme identique à ce cas. Il crée juste un nouveau fichier avec un nom différent, utilisez un numéro de version comme une partie arrière de son nom. Ouverture d'un fichier de session la première fois nécessite une recherche d'annuaire, mais vous pouvez cacher le dernier nom à la session.

Cela ne suppose qu'il ne peut y avoir un fil Writer pour une session donnée, ou que nous pouvons servir de médiateur entre deux threads d'écriture création du fichier, mais cela doit être vrai pour votre cas GC / Writer simple à travailler.

Pour Windows, vous pouvez utiliser le FILE_FLAG_DELETE_ON_CLOSE option CreateFile - qui cause le fichier à supprimer lorsque vous fermez la poignée. Mais je ne suis pas sûr que cela satisfait votre sémantique (parce que je ne crois pas que vous pouvez effacer l'attribut de suppression sur près.

Voici une autre pensée. Qu'en est-il de renommer le fichier avant de le supprimer? Vous ne pouvez pas fermer la fenêtre où l'écriture vient après que vous avez décidé de supprimer le fichier, mais si vous renommez le fichier avant de le supprimer? Puis, quand l'écriture est en elle verrez que le fichier de session n'existe pas et recréez.

La chose à garder à l'esprit est que vous ne pouvez pas fermer la fenêtre en question. À mon humble avis, il y a deux solutions:

  1. Ajout d'un drapeau comme djna mentionné ou
  2. Exiger qu'un être acquis mutex nommé par session qui a pour effet secondaire malheureux de sérialisation écrit sur la session.

Quel est l'inconvénient d'avoir un drapeau toolate? En d'autres termes, ce qui va mal si vous supprimez le fichier prématurément? Après tout votre système doit traiter le dossier ne pas être présent ...

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