Frage

Win32-s CreateFile hat FILE_FLAG_DELETE_ON_CLOSE,, aber ich bin auf Linux.

Ich will zu öffnen eine temporäre Datei, die immer gelöscht werden nach Beendigung des Programms.Ich konnte verstehen, dass bei einem Absturz kann es nicht praktikabel, dies zu garantieren, aber in jedem anderen Fall würde ich, wie es funktioniert.

Ich weiß über RAII.Ich weiß über Signale.Ich weiß über atexit(3).Ich weiß, ich kann die Datei öffnen und sofort löschen und die Datei bleibt so lange verfügbar, bis der Dateideskriptor wird geschlossen (die sogar Griffe einen Absturz).Keiner von diesen scheinen, wie eine vollständige und einfache Lösung:

  1. RAII:dort gewesen, getan, dass:Ich habe ein Objekt, dessen Destruktor löscht die Datei, aber der Destruktor wird nicht aufgerufen, wenn das Programm durch ein signal beendet wird.
  2. Signale:Ich Schreibe ein low-level-Bibliothek, die die macht der Registrierung ein signal-handler eine knifflige Angelegenheit.Was zum Beispiel, wenn die Anwendung verwendet die Signale selbst?Ich will nicht Schritt auf jedem Zehen.Ich könnte überlegen, einige kluge Nutzung des sigaction(2) zu bewältigen...aber noch nicht genug, dachte sich diese Möglichkeit noch nicht.
  3. atexit(3):scheinbar nutzlos, da es nicht aufgerufen, während abnormale Beendigung (z.B.über ein signal).
  4. preemptive unlink(2):das ist ziemlich gut, außer dass ich die Datei sichtbar bleiben im Dateisystem (ansonsten ist das system schwieriger zu überwachen und zu beheben).

Was würden Sie tun?

Weitere Erklärung

Ich erstellte ein detail in meinem ursprünglichen post von denen ich jetzt weiß, ich sollte enthalten haben.Die "Datei" in diesem Fall streng genommen nicht um eine normale Datei, sondern eine POSIX Message Queue.Ich erstelle es per mq_open().Es kann geschlossen werden, über mq_close() oder close() (das erstere ist ein alias für letzteres auf meinem system).Es kann entfernt werden aus dem system per mq_unlink().All dies macht es Analog zu einer regulären Datei, außer das kann ich nicht wählen Sie das Verzeichnis, in dem sich die Datei befindet.Dies macht die aktuelle beliebteste Antwort (indem Sie die Datei in /tmp) nicht praktikabel, da die "Datei" wird erstellt, indem das system in einem virtuellen Dateisystem mit sehr begrenzter Kapazität.(Ich habe das mounten der virtuellen Dateisystem in /dev/mqueue, nach dem Beispiel in man mq_overview) .

Dies erklärt auch, warum brauche ich den Namen sichtbar bleiben (die sofort-Verknüpfung-aufheben-nicht praktikabel Ansatz):die "Datei" muss geteilt werden zwischen zwei oder mehr Prozessen.

War es hilfreich?

Lösung

Die Anforderung, dass der name sichtbar bleibt, während der Prozess ausgeführt wird, macht dies schwer zu erreichen.Können Sie noch einmal überdenken, Anforderung?

Wenn nicht, dann ist es wahrscheinlich nicht die eine perfekte Lösung.Ich würde überlegen, die Kombination von signal-handling-Strategie mit dem, was Kamil Kisiel schlägt.Sie könnte verfolgen Sie die signal-Handler installiert, bevor Sie installieren der signal-Handler.Wenn der default-handler SIG_IGN, Sie würden in der Regel nicht installieren Ihre eigenen handler;wenn es ist SIG_DFL, würden Sie denken, dass;wenn es etwas anderes - eine user-defined signal handler - Sie würde sich erinnern, dass Zeiger, und installieren Sie Ihre eigenen.Wenn Ihr handler aufgerufen wurde, und Sie würde tun, was Sie tun müssen, und rufen Sie dann die Erinnerung handler, also die Verkettung der Handler.Sie würde auch installieren eine atexit () - handler.Würden Sie auch ein Dokument, dass Sie dies tun, und die Signale, für die Sie es tun.

Beachten Sie, dass die signal handling ist eine unvollkommene Strategie;SIGKILL kann nicht gefangen werden, und atexit () - handler wird nicht aufgerufen werden, und die Datei wird Links herum.

David zweiter kolbenringstoss Vorschlag - eine temporäre Datei name daemon - ist interessant.Für einfache Prozesse, es ist ausreichend;wenn der Prozess der Beantragung der temporären Datei Gabeln und erwartet, dass das Kind selbst die Datei danach (und beendet), dann wird der daemon ein problem hat, der erkennt, wenn der Letzte Prozess der Verwendung es stirbt, weil es nicht automatisch wissen, die Prozesse, die es zu öffnen.

Andere Tipps

Wenn Sie nur eine temporäre Datei, erstellen Sie es in /tmp oder in einem Unterverzeichnis davon.Dann machen beste Anstrengungen, um es zu entfernen, wenn Sie fertig, durch atexit(3) oder ähnlich.Solange Sie eindeutige Namen verwenden, nahm durch mkstemp(3) oder ähnlich, auch wenn es nicht gelöscht werden, weil von einem Absturz des Programms führen, die Sie nicht Gefahr, es zu Lesen, wieder auf der nachfolgenden läuft oder andere Bedingungen.

An diesem Punkt ist es nur ein system-level-problem zu halten /tmp sauber.Die meisten Distributionen wischen Sie auf starten oder Herunterfahren, oder führen Sie einen regelmäßigen cronjob zu löschen Sie alte Dateien.

Vielleicht hat jemand vorgeschlagen, das schon, aber ich bin nicht in der Lage, es zu lokalisieren, da alle Ihre Anforderungen, die beste, die ich denken kann, ist, um den Dateinamen irgendwie mitgeteilt zu einem übergeordneten Prozess, wie ein start-Skript, die reinigen, nachdem der Prozess stirbt, hatte es nicht zu tun.Dies ist vielleicht vor allem bekannt als Wachhund, aber dann mit der häufiger Anwendungsfall Hinzugefügt, um zu töten und/oder starten Sie den Prozess, wenn es irgendwie fehlschlägt.

Wenn Ihre übergeordneten Prozess stirbt, wie gut, bist du ziemlich viel Pech, aber die meisten Skript-Umgebungen sind Recht robust und nur selten sterben, es sei denn, das Skript ist gebrochen, die ist oft einfacher, halten Sie die richtige als ein Programm.

In der Vergangenheit habe ich die "temporäre" Datei-manager", die bleiben temporäre Dateien.

Eine Anfrage würde einen temporären Dateinamen aus dem manager-und dieser name wurde registriert.

Sobald Sie brauchen nicht die temporäre Datei-Namen nicht mehr, Sie informieren Sie den manager, und der Dateiname wird nicht registriert.

Nach Erhalt einer Kündigung signal, können alle registrierten temporären Dateien zerstört wurden.

Temporäre Dateinamen waren UUID basiert, um Kollisionen zu vermeiden.

Sie könnten den Prozess Gabel nach der Erstellung der Datei, und dann warten auf das Kind, um zu schließen, und dann kann der Elternteil verknüpfen Sie die Datei und beenden.

Ich kam gerade in stackoverflow und fand Sie hier :)

Wenn Sie problem ist die Verwaltung der mq-Dateien und halten Sie Sie aus, Sie häufen sich, die Sie nicht wirklich brauchen, um zu garantieren löschen von Dateien nach der Kündigung.Wenn Sie nur wollte, um nutzlose Dateien aus häufen sich, als ein Tagebuch kann alles, was Sie brauchen.Fügen Sie einen Eintrag in der journal-Datei nach einem mq geöffnet wird, wird ein weiterer Eintrag, wenn es geschlossen ist, und wenn Ihre Bibliothek initialisiert ist, überprüfen Sie für die Inkonsistenz in der Zeitschrift und was auch immer Maßnahmen, um die Inkonsistenzen zu korrigieren.Wenn Sie sich sorgen über abstürzt, wenn mq_open/mq_close aufgerufen wird, können Sie auch hinzufügen, einen journal-Eintrag, kurz bevor diese Funktionen aufgerufen werden.

  • Eine Buch-Führung-Verzeichnis für temporäre Dateien unter Ihrem Punkt-Verzeichnis.
  • Beim erstellen einer temp-Datei, erstellen Sie zuerst Buchhaltung-Datei in der Buchhaltung Verzeichnis Pfad oder die UUID zu, dass Ihre temp-Datei.
  • Erstellen temp-Datei.
  • Wenn die temp-Datei gelöscht, dann löschen Sie die Buchhaltung-Datei.
  • Wenn das Programm gestartet wird, Scannen Sie das Buch zu halten Verzeichnis für alle Dateien, die Pfade für temporäre Dateien und versuchen, Sie zu löschen, wenn gefunden, Sie löschen, book-keeping-Dateien.
  • (Melden sich lautstark, wenn ein Schritt fehlschlägt.)

Ich sehe keine Möglichkeiten, es zu tun keiner Weise einfacher.Dies ist die boilerplate jede Produktion Qualität Programm Durchlaufen muss;+500 Zeilen leicht.

Tun Sie wirklich müssen die Namen sichtbar bleiben?

Angenommen, Sie nehmen die Möglichkeit, sofort Verknüpfung der Datei.Dann:

  • preemptive unlink(2):das ist ziemlich gut, außer dass ich die Datei sichtbar bleiben im Dateisystem (ansonsten ist das system schwieriger zu überwachen und zu beheben).

    Sie können immer noch debug auf einer gelöschten Datei, denn es wird immer noch sichtbar unter /proc/$pid/fd/.So lange wie Sie wissen, die pids der Prozesse auflisten, Ihre geöffneten Dateien sollte einfach sein.

  • die Namen müssen auch dann sichtbar bleiben, während der normalen Betrieb, weil Sie zwischen Programmen gemeinsam genutzt.

    Sie können immer noch die gelöschte Datei öffnen zwischen Prozessen durch die übergabe um die Datei-Deskriptor-über Unix-domain-sockets.Finden Portable Weg, um pass-Datei-Deskriptor zwischen verschiedenen Prozessen weitere Informationen.

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