Anzahl der Dateideskriptoren: unterschiedlich zwischen / proc / sys / fs / file-nr und / proc / $ pid / fd?

9

Ich möchte überprüfen, wie viele Dateideskriptoren tatsächlich verwendet werden:

cat /proc/sys/fs/file-nr 
12750   0   753795

Die erste Spalte (12750) gibt die Anzahl der seit dem Start zugewiesenen Dateideskriptoren an.

Ich möchte wissen, warum sich die Nummer des folgenden Befehls unterscheidet (vorausgesetzt, dieser eine Liner gibt den richtigen Wert zurück:

for pid in $(lsof | awk '{ print $2 }' | uniq); do find /proc/$pid/fd/ -type l 2>&1 | grep -v "No"; done | wc -l

11069

HTF
quelle

Antworten:

10

lsoflistet nur die Prozess- ID auf. Um Informationen über Threads zu erhalten, sollten Sie verwenden ps -eLf. Nach dem man proc:

   / proc / [pid] / task (seit Linux 2.6.0-test6)
          Dies ist ein Verzeichnis, das jeweils ein Unterverzeichnis enthält
          Thread in den Prozess. Der Name jedes Unterverzeichnisses lautet
          numerische Thread-ID ( [tid] ) des Threads (siehe gettid (2) ).
          In jedem dieser Unterverzeichnisse gibt es eine Reihe von Dateien
          mit den gleichen Namen und Inhalten wie unter / proc / [pid]
          Verzeichnisse. Für Attribute, die von allen Threads gemeinsam genutzt werden,
          den Inhalt für jede der Dateien unter der Aufgabe / [tid]
          Unterverzeichnisse sind dieselben wie in der entsprechenden Datei
          im übergeordneten Verzeichnis / proc / [pid] (z. B. in einem Multithread-Verzeichnis
          Prozess haben alle Task / [tid] / cwd- Dateien das gleiche
          Wert als / proc / [pid] / cwd- Datei im übergeordneten Verzeichnis,
          da alle Threads in einem Prozess eine Arbeit teilen
          Verzeichnis). Für Attribute, die für jeden Thread unterschiedlich sind,
          Die entsprechenden Dateien unter task / [tid] können unterschiedlich sein
          Werte (z. B. können verschiedene Felder in jeder der Task- / [tid] / Statusdateien 
          für jeden Thread unterschiedlich sein).
In einem Multithread-Prozess wird der Inhalt des Das Verzeichnis / proc / [pid] / task ist nicht verfügbar, wenn das Hauptverzeichnis vorhanden ist Thread wurde bereits beendet (normalerweise durch Aufrufen pthread_exit (3) ).

Ich würde die Anzahl der offenen Dateideskriptoren berechnen, indem ich Folgendes ausführe:

ps -eL | awk 'NR > 1 { print $1, $2 }' | \
while read x; do \
    find /proc/${x% *}/task/${x#* }/fd/ -type l; \
done | wc -l

Das Ergebnis ist 17270.

Mal sehen, wie viele Dateideskriptoren seit dem Start zugewiesen wurden:

cat /proc/sys/fs/file-nr 
11616   0   398855

Warum gibt es einen Überschuss an Dateideskriptoren /proc/[pid]/task/[tid]/fdgegenüber der Anzahl der zugewiesenen Dateihandles in /proc/sys/fs/file-nr? Ich nehme an, dass sie durch forkuntergeordnete Prozesse erstellt werden:

man fork::

Das Kind erbt Kopien der offenen Dateideskriptoren des Elternteils.

man pthreads::

POSIX.1 erfordert auch , dass Threads gemeinsam nutzen eine Reihe von anderen Eigenschaften (dh diese Attribute sind prozess breit anstatt pro Thread): - Prozess - ID

  • übergeordnete Prozess-ID

  • Prozessgruppen-ID und Sitzungs-ID

  • Steuerterminal

  • Benutzer- und Gruppen-IDs

  • Dateideskriptoren öffnen

Quanten
quelle
Ich glaube nicht, dass die höhere Zahl in / proc / sys / fs / file-nr auf gegabelte Prozesse zurückzuführen ist. Die erste Antwort finden Sie hier: unix.stackexchange.com/questions/176967/… und auch dieses Zitat hier: (..aber der Kernel gibt diese Dateihandles nicht frei, wenn sie von der Anwendung freigegeben werden. Der Kernel recycelt stattdessen diese Dateihandles .) access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/…
yoshiwaan
3

http://www.netadmintools.com/part295.html Einige der geöffneten Dateien, die keine Dateideskriptoren verwenden: Bibliotheksdateien, das Programm selbst (ausführbarer Text) usw., wie oben aufgeführt. Diese Dateien werden an anderer Stelle in den Kernel-Datenstrukturen berücksichtigt (z. B. cat / proc / PID / maps, um die Bibliotheken anzuzeigen), verwenden jedoch keine Dateideskriptoren und erschöpfen daher nicht das maximale Dateideskriptor des Kernels.

SkoMine
quelle