2016-07-26 10 views
1

Was passiert mit einem Dateiobjekt in Python, wenn der Prozess beendet wird? Ist es wichtig, ob Python mit SIGTERM, SIGKILL, SIGHUP (etc.) oder durch eine KeyboardInterrupt Ausnahme beendet wird?Wie werden Dateiobjekte in Python bereinigt, wenn der Prozess beendet wird?

Ich habe einige Logging-Skripte, die kontinuierlich Daten erfassen und in eine Datei schreiben. Es ist mir egal, eine extra Bereinigung durchzuführen, aber ich möchte nur sicherstellen, dass die Protokolldatei nicht beschädigt wird, wenn Python abrupt beendet wird (z. B. könnte ich es im Hintergrund laufen lassen und den Computer einfach herunterfahren). Ich habe folgende Testskripte, um zu versuchen, um zu sehen, was passiert:

termtest.sh:

for i in $(seq 1 10); do 
    python termtest.py $i & export pypid=$! 
    sleep 0.3 
    echo $pypid 
    kill -SIGTERM $pypid 
done 

termtest.py:

import csv 
import os 
import signal 
import sys 

end_loop = False 


def handle_interrupt(*args): 
    global end_loop 
    end_loop = True 


signal.signal(signal.SIGINT, handle_interrupt) 

with open('test' + str(sys.argv[-1]) + '.txt', 'w') as csvfile: 
    writer = csv.writer(csvfile) 
    for idx in range(int(1e7)): 
     writer.writerow((idx, 'a' * 60000)) 
     csvfile.flush() 
     os.fsync(csvfile.fileno()) 
     if end_loop: 
      break 

Ich lief termtest.sh mit unterschiedlichen Signalen (geändert SIGTERM-SIGINT, SIGHUP und SIGKILL in termtest.sh) (Hinweis: Ich legte einen expliziten Handler in termtest.py für SIGINT da Python das nicht anders behandelt als Ctrl+C). In allen Fällen hatten alle Ausgabedateien nur vollständige Zeilen (keine partiellen Schreibvorgänge) und schienen nicht beschädigt zu sein. Ich setzte die flush() und fsync() Anrufe, um zu versuchen, sicherzustellen, dass die Daten so weit wie möglich auf die Festplatte geschrieben wurden, so dass das Skript die größte Chance hatte, während des Schreibens unterbrochen zu werden.

Also kann ich schlussfolgern, dass Python immer einen Schreibvorgang beendet, wenn es beendet wird und eine Datei in einem Zwischenzustand nicht verlässt? Oder hängt das vom Betriebssystem und dem Dateisystem ab (ich habe mit Linux und einer ext4-Partition getestet)?

Antwort

1

Es ist nicht so, wie Dateien so "bereinigt" werden, wie sie geschrieben werden. Es ist möglich, dass ein Programm mehrere Schreibvorgänge für einen einzelnen "Datenblock" (Zeile oder was auch immer) ausführt, und Sie könnten mitten in diesem Prozess unterbrechen und mit teilweise geschriebenen Datensätzen enden.

am C source Suche nach dem Modul csv, assembliert sie jede Zeile in einem String-Puffer, schreiben dann, dass ein einzelnen write() Anruf verwendet wird. Das sollte generell sicher sein; Entweder wird die Zeile an das Betriebssystem übergeben oder nicht, und wenn es an das Betriebssystem geht, wird alles geschrieben oder nicht (abgesehen natürlich von Hardware-Problemen, wo ein Teil davon in einen schlechten Sektor fallen könnte).

Der Schriftsteller Objekt ist ein Python-Objekt, und ein benutzerdefinierter Schriftsteller etwas seltsam in seinem write() tun könnte, dass diese brechen könnte, aber es ist ein normales Datei-Objekt unter der Annahme, sollte es in Ordnung sein.

Verwandte Themen