Dateideskriptor und Gabel

14

Wenn ein Kind gegabelt wird, erbt es die Dateideskriptoren des Elternteils. Wenn das Kind den Dateideskriptor schließt, was passiert dann? Wenn das Kind anfängt zu schreiben, was soll mit der Datei am Ende des Elternteils geschehen? Wer verwaltet diese Inkonsistenzen, Kernel oder Benutzer?

Wenn ein Prozess die closeFunktion zum Schließen einer bestimmten geöffneten Datei über den Dateideskriptor aufruft . In der Dateitabelle des Prozesses wird der Referenzzähler um eins dekrementiert. Da jedoch Eltern und Kind dieselbe Datei enthalten, beträgt der Referenzzähler 2 und nach dem Schließen wird er auf 1 reduziert. Da er nicht Null ist, verwendet der Prozess die Datei weiterhin problemlos.

Siehe Terrence Chan UNIX-Systemprogrammierung (Unix-Kernel-Unterstützung für Dateien).

Madan Ram
quelle
Okay, egal dieser letzte Kommentar;) In den Manpages für open()und fork()es gibt einen Unterschied zwischen einer Dateibeschreibung - oder einer Dateibeschreibung - die erstere bezieht sich auf die spätere, und obwohl die Deskriptoren in einer Gabel Kopien sind, sie beziehen sich auf die gleiche Beschreibung. Beim Testen ist es jedoch offensichtlich, dass das Schließen des Griffs des Kindes nicht den Griff des Elternteils schließt. Ich denke, es könnte einen subtilen Unterschied für die Verschachtelung von Daten machen, wenn beide Handles schreiben - aber das ist sowieso unbestimmt, also ist es nicht so wichtig, wie genau es passiert.
Goldlöckchen

Antworten:

27

Wenn ein Kind gegabelt wird, erbt es die Dateideskriptoren des Elternteils. Wenn das Kind den Dateideskriptor schließt, was passiert dann?

Es erbt eine Kopie des Dateideskriptors. Wenn Sie also den Deskriptor im Kind schließen, wird er für das Kind geschlossen, nicht jedoch für das Elternteil und umgekehrt.

Wenn das Kind anfängt zu schreiben, was soll mit der Datei am Ende des Elternteils geschehen? Wer verwaltet diese Inkonsistenzen, Kernel oder Benutzer?

Es ist genau (wie in, genau wörtlich) dasselbe wie zwei Prozesse, die in dieselbe Datei schreiben. Der Kernel plant die Prozesse unabhängig voneinander, sodass Sie wahrscheinlich verschachtelte Daten in der Datei erhalten.

Allerdings POSIX (auf dem * nix - Systeme weitgehend oder vollständig konform), schreibt vor , dass read()und write()Funktionen aus dem C - API (die Karte auf Systemaufrufe) sind „atomic in Bezug auf sie [...] , wenn sie arbeiten auf normale Dateien oder symbolische Links ". Die GNU C verspricht dies manuell auch vorläufig in Bezug auf Rohre (beachten Sie, dass die Standardeinstellung PIPE_BUF, die Teil des Vorbehalts ist, 64 kiB beträgt). Dies bedeutet, dass Aufrufe in anderen Sprachen / Tools, wie z. B. die Verwendung von echooder cat, in diesen Vertrag aufgenommen werden sollten. Wenn also zwei unabhängige Prozesse versuchen, "Hallo" und "Welt" gleichzeitig in dieselbe Pipe zu schreiben, wird das andere herauskommen Ende ist entweder "helloworld" oder "worldhello" und niemals so etwas wie "

Wenn ein Prozess die Funktion zum Schließen einer bestimmten geöffneten Datei über den Dateideskriptor aufruft. Die Dateitabelle des Prozesses verringert die Referenzanzahl um eins. Da jedoch Eltern und Kind dieselbe Datei enthalten (dort beträgt die Anzahl der Aktualisierungen 2 und nach dem Schließen verringert sie sich zu 1) da es nicht Null ist, verwendet der Prozess die Datei weiterhin ohne Probleme.

Es gibt ZWEI Prozesse, den Elternteil und das Kind. Es gibt keinen "Referenzzähler", der beiden gemeinsam ist. Sie sind unabhängig. WRT Was passiert, wenn einer von ihnen einen Dateideskriptor schließt, siehe die Antwort auf die erste Frage.

Goldlöckchen
quelle
1

Immer wenn fork()ein neues Kind erstellt wird, werden die Dateideskriptoren überhaupt nicht beibehalten - sie werden geändert.

Obwohl die Datei ein Duplikat ist, hat sie einen anderen Dateideskriptor.

mannukaushikece
quelle