Angenommen, ich lese (cat) eine Datei, während ein anderer Prozess ihren Inhalt neu schreibt. Ist die Ausgabe vorhersehbar? Was würde passieren?
Antwort1
Das hängt davon ab, was der Autor macht.
Wenn der Writer die vorhandene Datei überschreibt, wird der Reader den neuen Inhalt sehen, wenn der Writer den Reader überholt (falls überhaupt). Wenn Writer und Reader mit unterschiedlichen Geschwindigkeiten arbeiten, kann der Reader abwechselnd alten und neuen Inhalt sehen.
Wenn der Writer die Datei kürzt, bevor er mit dem Schreiben beginnt, stößt der Reader an dieser Stelle an das Dateiende.
Wenn der Writer eine neue Datei erstellt und diese dann unter dem alten Namen verschiebt, liest der Reader weiterhin aus der alten Datei. Wenn eine geöffnete Datei verschoben oder entfernt wird, lesen die Prozesse, die die Datei geöffnet haben, weiterhin aus derselben Datei. Wenn die Datei entfernt wird, bleibt sie tatsächlich auf der Festplatte (kann aber nicht erneut geöffnet werden), bis der letzte Prozess sie geschlossen hat.
Unix-Systeme haben in der Regel keine obligatorischenSchlösser. Wenn eine Anwendung sicherstellen möchte, dass ihre Schreib- und Lesekomponente sich nicht gegenseitig in die Quere kommen, ist es Aufgabe des Entwicklers, geeignete Sperren zu verwenden. Es gibt einige Ausnahmen, bei denen eine vom Kernel geöffnete Datei vor dem Schreiben durch Benutzeranwendungen geschützt sein kann, z. B. einSchleife-gemountetes Dateisystem-Image oder eine ausführbare Datei, die auf einigen Unix-Varianten ausgeführt wird.
Antwort2
Es handelt sich um einen klassischen Race Condition-Fall, das Ergebnis ist also per Definition unvorhersehbar.
Unter anderem hängt es davon ab,
fopen(3)
oderopen(2)
Schreibmodi,- wie/ob der Writer seine Ausgabe puffert,
- wie der Reader die Datei liest,
- der Geschwindigkeitsunterschied zwischen Lese- und Schreibgerät,
- der Zeitunterschied zwischen dem Beginn des Lesens und des Schreibens.
- Und natürlich wird die Sache auf modernen Multi-Core-Rechnern durch andere Faktoren auf niedrigerer Ebene (z. B. die Prozessplanung) noch komplizierter.
Wenn Sie eine Datei lesen können müssen, während sie neu geschrieben wird, können Sie den Writer eine temporäre Kopie der Datei erstellen lassen, diese ändern und dann wieder in die Originaldatei kopieren. Dies rsync
funktioniert beispielsweise auf diese Weise. Es gibt eine Reihe von Möglichkeiten, dies umzusetzen, aber nichts ist umsonst. Jede Methode hat ihre eigenen Nachteile und Auswirkungen.
Antwort3
Vorherige Antwortende hatten ausführlichere Erklärungen als diese, aber hier ist ein Trick, der definitiv genauso gut funktioniert und so ziemlich genau das tut, was er will:
$ tail -f <filename>
Zeigt Ihnen das Ende der Datei, während sie geschrieben wird. Praktisch, wenn Sie beispielsweise STDERR an eine Datei weiterleiten, sie aber trotzdem in einem anderen Terminalfenster sehen möchten.