2012-03-27 3 views
4

Ich möchte eine temporäre Datei unter Linux erstellen, während ich sicherstellen werde, dass die Datei verschwindet, nachdem mein Programm beendet wurde, selbst wenn es getötet wurde oder jemand im falschen Moment einen harten Neustart durchführt. Ist tmpfile() das alles für mich?Wie erstelle ich temporäre Dateien auf Linux, die automatisch nach sich aufräumen, egal was?

+0

@JarrodRoberson Ich werde das [race-condition] -Tag wieder hinzufügen - das ist alles über das Zeitfenster zwischen 'open()' und 'unlink()'. – thejh

+0

@JarrodRoberson: Äh, redest du nicht über einen Stillstand? Meine Definition von "Race Condition" ist etwas wie "es gibt einige parallele Prozesse und je nachdem, wie schnell sie in ihrer Rasse sind, passieren verschiedene Dinge". Schauen wir uns an, was die englische Wikipedia sagt: "Eine Race Condition oder Race Hazard ist ein Fehler in einem elektronischen System oder Prozess, bei dem die Ausgabe oder das Ergebnis des Prozesses unerwartet und kritisch von der Reihenfolge oder dem Timing anderer Ereignisse abhängt." – thejh

+0

* "Eine Race Condition tritt auf, wenn ein Programm nicht so funktioniert, wie es sein sollte, aufgrund einer unerwarteten Reihenfolge von Ereignissen, die Konflikte über die gleiche Ressource erzeugen." * Ich nahm an, dass Ihre Kommentare speziell auf einem * tot waren -lock * Dies ist ein Ergebnis des Versuches, eine Race-Bedingung (Konkurrenz der geteilten Ressource) zu beheben. Es ist immer noch nicht klar, was Ihr Anliegen ist, rufen Sie 'tmpfile()' und das Programm unerwartet beenden vor dem Aufruf von 'unlink()' ist die geringste Sorge, wenn Ihre Anwendung wirklich so fragil ist. –

Antwort

3

Sie scheinen vor beschäftigt mit der Idee, dass Dateien möglicherweise hinter etwas zurückbleiben, wie einige Race-Bedingung, sehe ich keine Erklärung, warum dies ein Anliegen ist.

"Eine Race-Bedingung tritt auf, wenn ein Programm aufgrund einer unerwarteten Reihenfolge von Ereignissen, die Konflikte über die gleiche Ressource verursachen, nicht so funktioniert, wie es sollte."

ich davon aus, dass aus Ihren Kommentar zu anderen Antworten Ihres Anliegen speziell auf Deadlock war, die ein Ergebnis des Versuchs ist einen Rennen-Zustand (Anstoß der gemeinsam genutzten Ressource) zu sanieren. Es ist immer noch nicht klar, was Ihr Anliegen ist, tmpfile() aufrufen und das Programm abnormal zu beenden, bevor diese Funktion ruft unlink() ist die geringste Ihrer Sorgen, wenn Ihre Anwendung wirklich so fragil ist.

Da es keine Erwähnung von Gleichzeitigkeit, Gewindeschneiden oder anderen Prozessen ist diesen Dateideskriptor auf diese temporären Datei zu teilen, ich immer noch nicht die Möglichkeit, für eine Race-Bedingung sieht, vielleicht das Konzept eines unvollständigen logischen Transaktion, aber das kann erkannt und aufgeräumt werden.

Der richtige Weg, um absolut sicher zu stellen, dass alle Dateisystemressourcen zugewiesen werden gereinigt ist nicht allein auf Ausfahrt eine Anwendung, sondern auch auch auf Start-up. All mein Server-Code, stellt sicher, dass alles von einem vorherigen Lauf bereinigt vor es beginnt und sich verfügbar macht.

Legen Sie Ihre Temp-Dateien in ein Unterverzeichnis in /tmp stellen Sie sicher, dass Ihre Anwendung dieses Unterverzeichnis beim Start und normalen Herunterfahren bereinigt. Sie können den Start Ihrer App mit einem Shell-Skript umbrechen, das abnormales (kill -9) Herunterfahren basierend auf PID Existenz erkennt und auch Aktivitäten aufräumt.

+1

Reinigung am Anfang ist nicht so einfach, wenn es mehrere Instanzen meines Programms gibt, oder? Auch IMO kann man von einem "Rennen" zwischen einem Killerprozess und der temporären Dateierstellung sprechen. – thejh

+0

* "mehrere Instanzen" * ist eine Form der Nebenläufigkeit ist in Ihrer Frage überhaupt nicht erwähnt. Wenn es ein Problem ist, müssen Sie Ihre Frage bearbeiten und alle * relevanten * Anliegen angeben, genau jetzt, da Ihre ausführlichen Kommentare zu allen Antworten nicht vollständig sind. –

+0

Nun, ich könnte "mehrere Instanzen" hinzufügen, ja. Aber ich könnte auch hinzufügen "nicht das einzige Programm auf dem System", "nicht unbedingt als root laufen" und so weiter - sind all diese Dinge nicht normal? – thejh

0

EDIT: Ja

überprüfte ich die tmpfile Quelle, und es in der Tat glglgl Trick nicht verwendet, und entriegelt sofort die Datei.

Original:

Ich würde Nein sagen. Get together sollte funktionieren, aber ich nehme an, dass es passieren kann, dass die Datei nach einem harten Neustart (z. B. aufgrund eines Stromausgangs) immer noch da ist. Aber das hängt von Ihrer Linux-Distribution und den verwendeten Einstellungen ab.

Wenn die temporäre Datei in einer Ramdisk erstellt wird, ist sie verschwunden (es gibt Unix-Distributionen, die z. B. einen RAM-basierten tmpfs für temporäre Dateien verwenden).

Oder wenn Sie eine Umgebung verwenden, die bestimmte Richtlinien bezüglich tmp hat, könnte es auch weg sein (vielleicht nicht sofort, aber oft gibt es Richtlinien, wie zB alle Dateien in/tmp entfernen, auf die nicht innerhalb eines Monats zugegriffen wird), aber es könnte auch auf einem Standard-Dateisystem sein, wo solche Regeln nicht durchgesetzt werden. In diesem Fall würde die Datei bleiben.

+0

"sofort"? Wie in "keine Rennbedingung" oder wie in "kleines Zeitfenster"? Ich würde "kleines Zeitfenster" sagen ... – thejh

+0

mit "sofort" meine ich, im Aufruf von tmpfile. Die Löschung erfolgt nicht am Ende des Programms über atexit (oder ähnlich). Aber es ist nicht "sofort" wie in - "keine Race Condition". Es gibt ein kleines Zeitfenster, in dem geöffnet wurde, aber die Verbindung nicht aufgehoben wird. Deshalb habe ich meine ursprünglichen Kommentare in der Post hinterlassen, weil es Lösungen für das Rennen bietet (wie RAM-Disk oder/tmp-Richtlinie). – flolo

+0

Nun, Reinigung '/ tmp' klingt wie ein Workaround, der machbar sein sollte ... obwohl es auf einem Server nur beim Booten möglich ist, eine schlechte Idee zu sein. Ich denke, ein Cronjob oder so sollte es für Dinge tun, die meine Programme erstellen, löschen Sie einfach alle ihre Dateien, die ungeöffnet sind ... aber es fühlt sich immer noch schlecht an. – thejh

2

nach tmpfile() -Handbuchseite:

Die Datei wird automatisch gelöscht, wenn es geschlossen ist oder das Programm beendet.

Ich habe nicht getestet, aber es scheint, es sollte tun, was Sie wollen.

Außerdem:

Die Standardposition, wenn TMPDIR nicht gesetzt ist, ist/tmp.

Wenn dann ein Neustart durchgeführt wird, ist /tmp leer.

+1

Werfen Sie einen Blick auf 'glibc/stdio-common/tmpfile.c'. Soweit ich das beurteilen kann, erstellt es zuerst eine Datei und hebt dann die Verknüpfung auf. – thejh

+0

Das Problem ist, wenn Ihr Programm unsauber beendet. z.B. wenn es defaults. AFAIK keine der Bereinigung in 'exit' wird auftreten. – daurnimator

+0

Wenn Sie sich den Code anschauen, den @thejh erwähnt, werden Sie sehen, dass die Datei direkt danach geöffnet und "gelöscht" (nicht verknüpft) wird. In UNIX wird eine Datei erst dann wirklich entfernt, wenn alle Dateideskriptoren, die auf diese Datei verweisen, geschlossen sind. Und alle Dateideskriptoren werden automatisch geschlossen, wenn der Prozess abbricht (AFAIK ist die Ursache egal). Daher muss keine Bereinigung ausgeführt werden, bevor der Prozess beendet wird. –

0

Der übliche Ansatz besteht darin, einen Signal-Handler einzurichten, der bereinigt wird, wenn das Programm unterbrochen wird. Dies behandelt nicht kill -9 oder einen physischen Neustart, der nicht abgefangen werden kann. Erstellen Sie temporäre Dateien in /tmp, die normalerweise beim Systemstart bereinigt werden. Alles, was dann bleibt, ist Leuten beizubringen, nicht kill -9 zu verwenden, wenn sie es nicht brauchen, aber das scheint ein harter Kampf zu sein.

+0

Hmmm ... manchmal muss man einfach etwas "töten". Nun, ich denke du hast Recht mit '/ tmp' - ich sollte es von Zeit zu Zeit wirklich löschen (hey, ich habe Dateien von 2011 in diesem Ordner). Allerdings mag ich den Gedanken nicht, dass es keine saubere Möglichkeit gibt, das zu tun ... – thejh

1

Wenn Sie nicht tmpfile() verwenden möchten, können Sie Ihre Datei sofort nach dem Erstellen unlink(). Es bleibt offen und präsentiert und zugeteilt, bis es geschlossen ist.

Aber bei einem harten Neustart wird möglicherweise ein fsck benötigt, um den Speicherplatz wiederherzustellen. Da dies jedoch immer der Fall ist, ist dies kein besonderer Nachteil dieses Ansatzes.

+0

Also, selbst wenn dieser Ansatz auftritt, dann, wenn der unwahrscheinliche Fall eintritt, dass mein Programm zwischen 'open()' und 'unlink()' stirbt, gibt es eine leere, nutzlose Datei, oder? Nun, ich denke, das ist viel besser als eine große, nutzlose Datei, wenn das Programm abstürzt ... – thejh

+0

@thejh Richtig. Das war auch mein Gedanke ... – glglgl

1

In Linux funktioniert mktemp Befehl funktioniert.

Verwandte Themen