Wie kann dieselbe FD in verschiedenen Prozessen auf dieselbe Datei verweisen?

25

Angenommen, ich habe Prozess 1 und Prozess 2 . Beide haben einen Dateideskriptor, der der Ganzzahl 4 entspricht.

In jedem Prozess verweist der Dateideskriptor 4 jedoch auf eine völlig andere Datei in der Open File Table des Kernels:

Bildbeschreibung hier eingeben

Wie ist das möglich? Soll ein Dateideskriptor nicht der Index für einen Datensatz in der Open File Table sein?

Pithikos
quelle
1
Gute Frage! Ich vermute, dass die Dateideskriptoren übersetzt sind, so dass die fd 4in beiden Prozessen relativ zur eigenen Anzahl offener fds ist. Fd's 0-2(stdin, stdout, sdterr) werden immer für einen neuen Prozess geöffnet und die Nummern sind nicht nur für diesen Prozess reserviert.
@ jw013 Ich dachte das kommt mir bekannt vor. \ @Pithikos Wie ist das nicht ein Duplikat?
Michael Mrozek
1
Dies ist ein schlechtes Diagramm - es sollte zeigen, dass der Dateideskriptor 4 den vierten Eintrag der Dateideskriptortabelle auf der linken Seite bedeutet [nun, der fünfte Eintrag wird von Null an gezählt] und keinen Eintrag, der eine "4" enthält. Die tatsächliche "4" befindet sich in Ihrer Userspace-Variable, die die Nummer enthält. Das Diagramm in der anderen Frage ist viel besser.
Random832
2
@ Random832 Naja, wenn ich wüsste, welches Diagramm richtig ist, hätte ich diese Frage wahrscheinlich nie gestellt.
Pithikos

Antworten:

35

Der Dateideskriptor, dh der 4in Ihrem Beispiel, ist der Index in der prozessspezifischen Dateideskriptortabelle , nicht in der geöffneten Dateitabelle. Der Dateideskriptoreintrag selbst enthält einen Index zu einem Eintrag in der globalen offenen Dateitabelle des Kernels sowie Dateideskriptorflags.

jw013
quelle
2
Für den Datensatz gibt es auf den meisten Systemen nur ein "Dateideskriptor-Flag", das Close-On-Exec-Flag. Alle anderen "per-fd" -Zustände (einschließlich des Offsets und des Zugriffsmodus) sind Teil des Eintrags in der geöffneten Dateitabelle.
Random832
24

Jeder Prozess hat eine eigene Dateideskriptortabelle. Der Dateideskriptor 4 in Prozess 1234 zeigt in die Tabelle von Prozess 1234. Der Dateideskriptor 4 in Prozess 5678 zeigt in die Tabelle von Prozess 5678. Ein vertrauter Fall sind die Dateideskriptoren 0, 1 und 2, die für jeden Prozess die Standardeingabe, die Standardausgabe und den Standardfehler darstellen und zeigen, wohin diese umgeleitet wurden.

Ein Prozess kann dieselbe Datei mehrmals öffnen. Dies kann zufällig passieren, wenn beispielsweise die Standardausgabe und der Standardfehler eines Prozesses auf dasselbe Terminal oder dieselbe Datei umgeleitet werden. Die zugrunde liegenden Einträge in der Dateitabelle (z. B. Linuxstruct file ) enthalten mehr als nur Informationen über die Datei. Sie enthalten auch Öffnungsmodi (z. B. Lesen oder Schreiben) und andere Zustände (z. B. Flags, z. B. Close-on-Exec). Beispielsweise könnte ein Prozess ein Terminal haben, das nur zum Lesen in Dateideskriptor 0 geöffnet ist, und dasselbe Terminal, das nur zum Schreiben in Dateideskriptor 2 geöffnet ist. Ein Prozess möchte möglicherweise lseekzwei verschiedene Positionen in derselben Datei haben und verwendet diese dup, um zwei Handles für diese Datei zu erhalten.

Gilles 'SO - hör auf böse zu sein'
quelle
2
Das ist nicht ganz richtig. Tut laut Manpage / Specs dupgenau das, was es verspricht: Beide resultierenden Deskriptoren verweisen auf den gleichen Eintrag in der Dateitabelle und teilen sich damit den gleichen Versatz. Ich bin mir ziemlich sicher, dass Sie opendie Datei zweimal benötigen, um zwei verschiedene Einträge in der Dateitabelle zu erhalten.
jw013
@Gilles "Dateideskriptor 4 in Prozess 1234 zeigt in die Tabelle von Prozess 1234". Welchen Tisch meinst du? Soweit ich weiß, ist die einzige Tabelle in diesem Prozess die Dateideskriptortabelle, in der jeder Datensatz auf die einzelne Open File Table des Kernels verweist .
Pithikos
Eine genauere Beschreibung finden Sie unter unix.stackexchange.com/questions/195057/… .
Gilles 'SO- hör auf böse zu sein'
8

Jeder Prozess hat eine eigene Dateideskriptortabelle. Das ist alles.

In der UNIX-Netzwerkprogrammierung von Richard Stevens ist alles sehr gut beschrieben, wenn Sie es gründlich lernen möchten.

Michał Šrajer
quelle
Auf welche Tabelle beziehen Sie sich?
Pithikos
1
Dateideskriptortabelle
Michał Šrajer
7

Würde eine zusätzliche Indirektionsebene Ihr Problem nicht beheben? ("Alle Probleme bei der Computerprogrammierung können durch eine zusätzliche Indirektionsebene gelöst werden" - einigermaßen kluger Graubart). Das heißt, die kleine Ganzzahl in jedem Prozess endet als Index in einem Array von Kernel-Space-Indizes pro Prozess in der "Open File Table".

Bruce Ediger
quelle
2
Die Quelle weise Graubart ist wahrscheinlich David Wheeler. Es scheint, dass er auch sagte: " Aber das wird normalerweise ein anderes Problem schaffen. " :)
jw013