607 Stimmen

Was sind Dateideskriptoren, in einfachen Worten erklärt?

  1. Wie würde eine vereinfachte Beschreibung von Dateideskriptoren im Vergleich zu Wikipedia aussehen? Warum sind sie erforderlich? Nehmen wir Shell-Prozesse als Beispiel, und was bedeutet das für sie?

  2. Enthält eine Prozesstabelle mehr als einen Dateideskriptor. Wenn ja, warum?

4 Stimmen

Was ist mit den Konzepten von stdin, stdout, stderr usw.? Ich habe eine Instanz wie z.B. einen Browser-Prozess geöffnet und dieser hat einige temporäre Dateien für die Anzeige meiner HTML-Dateien geöffnet. Der Prozess verwendet die gleiche fd zum Lesen / Schreiben? Auch die Prozesstabelle ....... hat Einträge wie fd0 Zeiger fd1 Zeiger fd2 Zeiger ..... bedeutet das, dass alle diese Dateien im RAM sind? Warum sonst Zeiger ?

87 Stimmen

Wenn Sie eine Datei öffnen, erstellt das Betriebssystem einen Stream zu dieser Datei und verbindet diesen Stream mit der geöffneten Datei, wobei der Deskriptor diesen Stream darstellt. In ähnlicher Weise gibt es einige Standard-Streams, die vom Betriebssystem erstellt werden. Diese Streams sind mit Ihrem Terminal anstelle von Dateien verbunden. Wenn Sie also etwas im Terminal schreiben, geht es in den stdin-Stream und das Betriebssystem. Und wenn Sie im Terminal den Befehl "ls" eingeben, schreibt das Betriebssystem die Ausgabe in den stdout-Stream. stdout ist mit Ihrem Bildschirm verbunden, so dass Sie die Ausgabe dort sehen können.

2 Stimmen

Was das Beispiel des Browsers betrifft, so ist es nicht notwendig, dass der Browser die geöffneten Dateien speichert. Es hängt von der Implementierung des Browsers ab, aber in den meisten Fällen öffnet der Browser eine temporäre Datei, schreibt die Datei und schließt die Datei, so dass es nicht notwendig ist, dass die Datei geöffnet ist, auch wenn die Webseite geöffnet ist. Und der Deskriptor enthält nur die Informationen der Datei und hält die Datei nicht unbedingt im RAM. Wenn Sie die Daten aus einem Deskriptor lesen, liest das Betriebssystem die Daten von der Festplatte. Die Informationen im Dateideskriptor stellen nur den Speicherort der Datei auf der Festplatte usw. dar.

812voto

Tayyab Punkte 9517

Mit einfachen Worten: Wenn Sie eine Datei öffnen, erstellt das Betriebssystem einen Eintrag, der diese Datei repräsentiert und die Informationen über die geöffnete Datei speichert. Wenn also 100 Dateien in Ihrem Betriebssystem geöffnet sind, gibt es 100 Einträge im Betriebssystem (irgendwo im Kernel). Diese Einträge werden durch Ganzzahlen wie (...100, 101, 102....) dargestellt. Diese Eintragsnummer ist der Dateideskriptor. Es handelt sich also nur um eine ganze Zahl, die eindeutig eine geöffnete Datei für den Prozess darstellt. Wenn Ihr Prozess 10 Dateien öffnet, hat Ihre Prozesstabelle 10 Einträge für Dateideskriptoren.

Wenn Sie einen Netzwerk-Socket öffnen, wird dieser ebenfalls durch eine Ganzzahl dargestellt und Socket Descriptor genannt. Ich hoffe, Sie verstehen das.

0 Stimmen

Großartiger Tayyab. Ich habe einige Kommentare in der Frage bitte Antwort auf, dass zu setzen.

13 Stimmen

Das ist auch der Grund, warum Ihnen die Dateideskriptoren ausgehen können, wenn Sie viele Dateien auf einmal öffnen. Das wird verhindern, dass *nix-Systeme laufen, da sie Deskriptoren öffnen, um Dinge in /proc Die ganze Zeit über.

3 Stimmen

Streng genommen enthält die Prozesstabelle keine Dateideskriptoren, die Dateideskriptoren werden in der u-Struktur des Prozesses gehalten und sind daher eindeutig für den Prozess.

191voto

Beano Punkte 7081

Ein Dateideskriptor ist ein undurchsichtiges Handle, das an der Schnittstelle zwischen Benutzer- und Kernelbereich verwendet wird, um Datei-/Socket-Ressourcen zu identifizieren. Wenn Sie also open() o socket() (Systemaufrufe für die Schnittstelle zum Kernel) erhalten Sie einen Dateideskriptor, bei dem es sich um eine ganze Zahl handelt (in Wirklichkeit ist es ein Index in der Prozess-U-Struktur - aber das ist nicht wichtig). Wenn Sie also direkt mit dem Kernel kommunizieren wollen, verwenden Sie Systemaufrufe zu read() , write() , close() usw. ist das von Ihnen verwendete Handle ein Dateideskriptor.

Die Systemaufrufe werden von einer Abstraktionsschicht überlagert, nämlich der stdio Schnittstelle. Diese bietet mehr Funktionen/Features als die grundlegenden Systemaufrufe. Für diese Schnittstelle ist das undurchsichtige Handle, das Sie erhalten, ein FILE* die von der Funktion fopen() anrufen. Es gibt viele, viele Funktionen, die den stdio Schnittstelle fprintf() , fscanf() , fclose() , die Ihnen das Leben erleichtern sollen. In C, stdin , stdout und stderr son FILE* , die unter UNIX jeweils Dateideskriptoren entsprechen 0 , 1 y 2 .

10 Stimmen

Ich persönlich denke, dass diese Antwort besser ist als die markierte. Hochgevotet.

161voto

Shekhar Kumar Punkte 1940

Aus berufenem Munde: APUE (Richard Stevens).
Für den Kernel sind alle geöffneten Dateien durch Dateideskriptoren gekennzeichnet. Ein Dateideskriptor ist eine nicht-negative Zahl.

Wenn wir eine bestehende Datei öffnen oder eine neue Datei erstellen, gibt der Kernel einen Dateideskriptor an den Prozess zurück. Der Kernel unterhält eine Tabelle aller offenen Dateideskriptoren, die in Gebrauch sind. Die Zuteilung von Dateideskriptoren erfolgt in der Regel sequentiell, und sie werden der Datei als nächster freier Dateideskriptor aus dem Pool der freien Dateideskriptoren zugeteilt. Wenn wir die Datei schließen, wird der Dateideskriptor freigegeben und steht für eine weitere Zuteilung zur Verfügung.
Siehe dieses Bild für weitere Details:

Two Process

Wenn wir eine Datei lesen oder schreiben wollen, identifizieren wir die Datei mit dem Dateideskriptor, der von öffnen() o erstellen() Funktionsaufruf, und verwenden Sie ihn als Argument für entweder lesen() o schreiben() .
UNIX-System-Shells assoziieren den Dateideskriptor 0 per Konvention mit Standard-Eingang eines Prozesses, Dateideskriptor 1 mit Standard-Ausgang und Dateideskriptor 2 mit Standardfehler .
Der Dateideskriptor reicht von 0 bis OPEN_MAX. Der Maximalwert des Dateideskriptors kann wie folgt ermittelt werden ulimit -n . Weitere Informationen finden Sie im dritten Kapitel des APUE-Buches.

1 Stimmen

Da 0, 1, 2 mit "stdin", "stdout" und "stderr" eines Prozesses verbunden sind, können wir diese Deskriptoren gleichzeitig für verschiedene Prozesse verwenden?

1 Stimmen

@Tarik: Dateideskriptoren sind pro Prozess. Um dies zu sehen, laden Sie osquery und ausführen osqueryi <<< echo '.all process_open_files' in einer Bash-Shell.

100voto

prosti Punkte 34344

Andere Antworten fügten großartige Dinge hinzu. Ich werde nur meine 2 Cents hinzufügen.

Laut Wikipedia wissen wir sicher: ein Dateideskriptor ist eine nicht-negative ganze Zahl. Das Wichtigste, was meiner Meinung nach fehlt, wäre zu sagen:

Dateideskriptoren sind an eine Prozess-ID gebunden.

Wir wissen, dass die bekanntesten Dateideskriptoren 0, 1 und 2 sind. 0 entspricht STDIN , 1 bis STDOUT und 2 bis STDERR .

Nehmen wir als Beispiel die Shell-Prozesse und was bedeutet das für sie?

Prüfen Sie diesen Code

#>sleep 1000 &
[12] 14726

Wir haben einen Prozess mit der ID 14726 (PID) erstellt. Unter Verwendung der lsof -p 14726 können wir die Dinge so bekommen:

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
sleep   14726 root  cwd    DIR    8,1     4096 1201140 /home/x
sleep   14726 root  rtd    DIR    8,1     4096       2 /
sleep   14726 root  txt    REG    8,1    35000  786587 /bin/sleep
sleep   14726 root  mem    REG    8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep   14726 root  mem    REG    8,1  2030544  137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep   14726 root  mem    REG    8,1   170960  137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

Die 4. Spalte FD und die nächste Spalte TYPE entsprechen dem Dateideskriptor und dem Dateideskriptortyp.

Einige der Werte für den FD können sein:

cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device

Aber der eigentliche Dateideskriptor ist unter:

NUMBER – Represent the actual file descriptor. 

Das Zeichen nach der Zahl, z. B. "1u", steht für den Modus, in dem die Datei geöffnet wird. r für Lesen, w für Schreiben, u für Lesen und Schreiben.

TYPE gibt den Typ der Datei an. Einige der Werte von TYPEs sind:

REG – Regular File
DIR – Directory
FIFO – First In First Out

Aber alle Dateideskriptoren sind CHR - Zeichenspezialdatei (oder Zeichengerätedatei)

Jetzt können wir die Dateideskriptoren für STDIN , STDOUT y STDERR einfach mit lsof -p PID oder wir können dasselbe sehen, wenn wir ls /proc/PID/fd .

Beachten Sie auch, dass die Dateideskriptor-Tabelle, die der Kernel verwaltet, nicht mit der Datei- oder Inodes-Tabelle identisch ist. Diese sind getrennt, wie einige andere Antworten erklärt haben.

fd table

Sie fragen sich vielleicht, wo diese Dateideskriptoren physikalisch sind und was in /dev/pts/6 zum Beispiel

sleep   14726 root    0u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    1u   CHR  136,6      0t0       9 /dev/pts/6
sleep   14726 root    2u   CHR  136,6      0t0       9 /dev/pts/6

Nun, /dev/pts/6 lebt nur in der Erinnerung. Es handelt sich nicht um normale Dateien, sondern um so genannte Zeichengerätedateien . Sie können dies mit überprüfen: ls -l /dev/pts/6 und sie werden beginnen mit c in meinem Fall crw--w---- .

Nur zur Erinnerung: Die meisten Linux-ähnlichen Betriebssysteme definieren sieben Dateitypen:

  • Reguläre Dateien
  • Verzeichnisse
  • Zeichengerätedateien
  • Gerätedateien sperren
  • Lokale Domain-Sockets
  • Benannte Leitungen (FIFOs) und
  • Symbolische Verbindungen

5 Stimmen

Danke. In der Tat ist es wichtig, darauf hinzuweisen, dass es sich um einen Prozess handelt! Das hilft, die Dinge besser zu visualisieren.

4 Stimmen

Die vom Betriebssystem definierten Dateitypen, die Sie in Ihrer Antwort erwähnt haben, helfen wirklich dabei, Dateien auf einer niedrigeren Ebene zu verstehen.

0 Stimmen

Wo erfahre ich mehr über Dateideskriptoren und was damit zusammenhängt?

28voto

Abhishek Kamal Punkte 610

Dateideskriptoren (FD) :

  • En Linux/Unix ist alles eine Datei. Normale Dateien, Verzeichnisse, und sogar Geräte sind Dateien. Jede Datei hat eine zugehörige Nummer, die Dateideskriptor (FD) genannt wird.

  • Ihr Bildschirm hat auch einen Dateideskriptor. Wenn ein Programm ausgeführt wird wird die Ausgabe an den Dateideskriptor des Bildschirms gesendet, und Sie sehen Programmausgabe auf Ihrem Bildschirm. Wenn die Ausgabe an den File Descriptor Deskriptor des Druckers gesendet wird, würde die Programmausgabe gedruckt.

    Fehlerumleitung :
    Wenn Sie ein Programm/Befehl am Terminal ausführen, sind immer 3 Dateien geöffnet

    1. Standardeingabe
    2. Standardausgabe
    3. Standardfehler.

    Diese Dateien sind immer vorhanden, wenn ein Programm ausgeführt wird. Wie bereits erläutert, ist jeder dieser Dateien ein Dateideskriptor zugeordnet. diesen Dateien zugeordnet.
    Datei Datei Deskriptor
    Standard-Eingang STDIN 0
    Standardausgang STDOUT 1
    Standardfehler STDERR 2

  • Zum Beispiel kann man bei der Suche nach Dateien typischerweise Fehler bei der Erlaubnisverweigerung oder andere Fehler. Diese Fehler können in einer bestimmten Datei gespeichert werden.
    Beispiel 1

$ ls mydir 2>errorsfile.txt

Der Dateideskriptor für Standardfehler ist 2.
Wenn es kein Verzeichnis mit dem Namen mydir gibt, wird die Ausgabe des Befehls in der Datei errorfile.txt gespeichert
Mit "2>" leiten wir die Fehlerausgabe in eine Datei namens "errorfile.txt" um
Auf diese Weise wird die Programmausgabe nicht mit Fehlern überfrachtet.

Ich hoffe, Sie haben Ihre Antwort erhalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X