2009-12-19 3 views
1

Veuillez noter qu'il ne s'agit pas d'un doublon de File r/w locking and unlink. (La différence - plate-forme.Les opérations de fichiers comme le verrouillage et la suppression ont une sémantique totalement différente, ainsi la différence serait différente).Déverrouillage et suppression de fichier en tant qu'opération unique

J'ai un problème suivant. Je veux créer un stockage de session basé sur le système de fichiers où chaque donnée de session est stockée dans un fichier simple nommé avec des identifiants 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 un seul processus mais absolument pas trivial lorsque vous travaillez avec plusieurs processus ou même sur des dossiers partagés.

La solution que je pensais plus simple au sujet é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 AFIAK je ne peux pas appeler DeleteFile le fichier verrouillé opended (contrairement à Unix où le verrouillage des fichiers est pas obligatoire et supprimer le lien est autorisé pour les fichiers ouverts.

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

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

Quelqu'un a-t-il une idée de comment un tel problème peut être résolu? Y a-t-il des astuces qui permettent de combiner le verrouillage et la suppression du fichier ou de faire une 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.

+1

Certainement ressemble à une dupe pour moi. S'il vous plaît expliquer les différences, ou il peut très bien être fermé. –

+0

Ajout explenation - POSIX et Win32 requis solutions totalement différentes – Artyom

Répondre

2

Je ne comprends pas vraiment comment cela est censé fonctionner. Cependant, la suppression d'un fichier ouvert par un autre processus est possible. Le processus qui crée le fichier doit utiliser l'indicateur FILE_SHARE_DELETE pour l'argument dwShareMode de CreateFile(). Un appel DeleteFile() suivant réussira. Le fichier n'est en fait supprimé du système de fichiers que lorsque le dernier descripteur est fermé.

+0

Ok, je vois, on dirait que je n'ai pas du tout besoin de LockFile. Si je spécifie 'CreateFile (" file.txt ", ..., FILE_SHARE_DELETE, ...)' sans 'FILE_SHARE_READ | FILE_SHARE_WRITE' un seul thread/processus serait capable de maintenir le fichier ouvert. Ai-je raison? Donc, je n'ai pas besoin de verrouillage du tout, ai-je raison? – Artyom

+0

En fait, il ressemble à Windows trop différent de Unix: Win32: CreateFile (ok), DeleteFile (ok), CreateFile (échouer). Unix: ouvert (ok), unlink (ok), ouvert (ok - un autre fichier). C'est ce qui m'avait dérouté. – Artyom

1

Vous avez actuellement des données dans l'enregistrement qui permettent au GC de déterminer si l'enregistrement a expiré. Que diriez-vous d'étendre cette information de gestion avec un indicateur "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 approche de verrouillage optimiste. Cela nécessite une certaine complexité supplémentaire dans Writer, mais vous ne dépendez plus des rides spécifiques au système d'exploitation.

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 « toolate » cas

Modifié 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 

Le WRI ter peut traiter le drapeau "tooLate" comme identique à ce cas.Il crée simplement un nouveau fichier , avec un nom différent, utilisez un numéro de version comme partie finale de son nom. L'ouverture d'un fichier de session la première fois nécessite une recherche dans le répertoire, mais vous pouvez ensuite stocker le nom le plus récent dans la session. Cela suppose qu'il ne peut y avoir qu'un seul thread Writer pour une session donnée, ou que nous pouvons servir de médiateur entre deux threads Writer créant le fichier, mais cela doit être vrai pour que votre simple CG/Writer fonctionne.

+0

Le problème que je veux écrivain pour "désactiver" TooLate - ce qui signifie renouveler le fichier. Donc la solution que vous proposez n'est pas valide pour moi. Le deuxième point (l'auteur essaye d'écrire alors il devrait créer le fichier) – Artyom

+0

Vous n'avez pas besoin de désactiver tooLate, vous pouvez réorganiser les opérations. Je vais modifier pour expliquer. – djna

0

Pour Windows, vous pouvez utiliser l'option FILE_FLAG_DELETE_ON_CLOSE pour CreateFile - qui entraînera la suppression du fichier lorsque vous fermez la poignée. Mais je ne suis pas sûr que cela satisfasse votre sémantique (parce que je ne crois pas que vous pouvez effacer l'attribut delete-on-close.)

Voici une autre idée: qu'en est-il de renommer le fichier avant de le supprimer? Ne fermez pas la fenêtre où l'écriture arrive après que vous ayez décidé de supprimer le fichier mais que se passe-t-il si vous renommez le fichier avant de le supprimer? Alors, lorsque l'écriture arrive, le fichier de session n'existe pas et le recrée.

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. Nécessite l'acquisition d'une mutex par session nommée qui a le malheureux effet secondaire de sérialiser les écritures sur la session.

Quel est l'inconvénient d'avoir un indicateur TooLate? En d'autres termes, que se passe-t-il si vous supprimez le fichier prématurément? Après tout votre système doit traiter avec le fichier ne pas être présent ...

Questions connexes