Frage

Bitte beachten Sie, dass dies nicht doppelt ist Datei R/W Locking und Unglied. (Die Differenz - Plattform. Operationen von Dateien wie Sperren und Löschen haben völlig unterschiedliche Semantik, daher wäre die SPOTION unterschiedlich).

Ich habe das folgende Problem. Ich möchte einen systembasierten Sitzungsspeicher erstellen, bei dem jede Sitzungsdaten in einer einfachen Datei gespeichert werden, die mit Sitzungs -IDs benannt ist.

Ich möchte API folgen: write(sid,data,timeout), read(sid,data,timeout), remove(sid)Wo SID == Dateiname, ich möchte auch eine Art GC haben, das alle zeitgesteuerten Sitzungen entfernen kann.

Ganz einfache Aufgabe, wenn Sie mit einem einzigen Prozess arbeiten, aber absolut nicht trivial sind, wenn Sie mit mehreren Prozessen oder sogar über gemeinsamen Ordnern arbeiten.

Die einfachste Lösung, über die ich dachte, war:

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)

Aber Afiak kann ich nicht anrufen DeleteFile Auf der geplanten gesperrten Datei (im Gegensatz zu Unix, bei dem die Dateisperrung nicht obligatorisch ist und das Unglied für geöffnete Dateien zulässig ist.

Aber wenn ich setze DeleteFile Außerhalb der Schließschleife kann ein schlechtes Szenario passieren

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

Hat jemand eine Idee, wie ein solches Problem gelöst werden kann? Gibt es irgendwelche Tricks, mit denen die Entfernung und Entfernung von Dateien mit dem Kombination von Dateien ermöglichen oder die Betriebsatomic (Win32) bearbeiten oder den Betrieb bearbeiten?

Anmerkungen:

  • Ich möchte keine Datenbank verwenden,
  • Ich suche nach einer Lösung für Win32 -API für NT 5.01 und höher

Vielen Dank.

War es hilfreich?

Lösung

Ich verstehe nicht wirklich, wie das funktionieren soll. Das Löschen einer Datei, die durch einen anderen Prozess geöffnet wird, ist jedoch möglich. Der Prozess, bei dem die Datei erstellt wird, muss das Flag File_Share_Delete für das DWSHAREMODE -Argument von createFile () verwenden. Ein nachfolgender Aufruf von DeleteFile () wird erfolgreich sein. Die Datei wird nicht aus dem Dateisystem entfernt, wenn der letzte Handle geschlossen ist.

Andere Tipps

Sie haben derzeit Daten in dem Datensatz, mit denen der GC feststellen kann, ob der Datensatz abgestimmt ist. Wie wäre es mit der Ausweitung dieser Housekeeping -Informationen mit einer Flagge "ToolateWealreadyTimeditout".

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

Mit anderen Worten, wir verwenden eine Art optimistischer Sperransatz. Dies erfordert eine zusätzliche Komplexität im Verfasser, aber jetzt sind Sie nicht auf OS-Specifc-Falten angewiesen.

Ich bin mir nicht klar, was im Fall passiert:

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

Was auch immer Sie für diesen Fall geplant haben, kann auch im Fall "Toolate" verwendet werden

Bearbeitet, um hinzuzufügen:

Sie haben gesagt, dass es für diese Sequenz gültig ist:

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

Der Schriftsteller kann die "Toolate" -Fahne als identisch mit diesem Fall behandeln. Es schafft einfach a Neu Verwenden Sie mit einem anderen Namen eine Versionsnummer als nachfolgender Bestandteil des Namens. Das Eröffnen einer Sitzungsdatei zum ersten Mal erfordert eine Verzeichnissuche, aber dann können Sie den neuesten Namen in der Sitzung verstauen.

Dies geht davon aus, dass es nur einen Schriftsteller -Thread für eine bestimmte Sitzung geben kann oder dass wir zwischen zwei Writer -Threads vermitteln können, die die Datei erstellen, aber dies muss für Ihren einfachen GC/Writer -Fall zu funktionieren.

Für Windows können Sie die verwenden Datei_flag_delete_on_close Option zum createFile - Dies führt dazu, dass die Datei beim Schließen des Griffs gelöscht wird. Aber ich bin mir nicht sicher, ob dies Ihre Semantik erfüllt (weil ich nicht glaube, dass Sie das Attribut für Löschungen auf der Close-Clase löschen können.

Hier ist ein weiterer Gedanke. Was ist mit der Umbenennung der Datei, bevor Sie sie löschen? Sie können das Fenster, in dem das Schreiben hereinkommt, einfach nicht schließen, nachdem Sie sich entschlossen haben, die Datei zu löschen, aber was ist, wenn Sie die Datei umbenennen, bevor Sie sie löschen? Wenn das Schreiben hereinkommt, wird er sehen, dass die Sitzungsdatei nicht existiert und sie neu erstellt.

Das Wichtigste ist, dass Sie das betreffende Fenster einfach nicht schließen können. IMHO Es gibt zwei Lösungen:

  1. Hinzufügen einer Flagge wie erwähnte DJNA oder
  2. Verlangen, dass eine pro-Sitzung namens Mutex erworben wird, die den unglücklichen Nebeneffekt der Serialisierungsschreibungen auf die Sitzung hat.

Was ist der Nachteil einer Werkzeugflagge? Mit anderen Worten, was geht schief, wenn Sie die Datei vorzeitig löschen? Nachdem Ihr System nicht vorhanden ist, ist Ihr System nicht vorhanden ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top