Für welchen Prozess ist `/ proc / self /`?

40

https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s3-proc-self.html sagt

Das /proc/self/Verzeichnis ist eine Verknüpfung zum aktuell ausgeführten Prozess.

Es werden immer mehrere Prozesse gleichzeitig ausgeführt. Welcher Prozess ist also "der aktuell ausgeführte Prozess"?

Hat "der aktuell ausgeführte Prozess" irgendetwas damit zu tun, welcher Prozess derzeit auf der CPU ausgeführt wird, unter Berücksichtigung der Kontextumschaltung?

Hat "der aktuell laufende Prozess" nichts mit Vordergrund- und Hintergrundprozessen zu tun?

Tim
quelle
15
Der Prozess /proc/self, der natürlich bewertet .
Charles Duffy
8
Welche Person kann ich und mich beziehen sich auf?
Jeffrey Bosboom

Antworten:

64

Dies hat nichts mit Vordergrund- und Hintergrundprozessen zu tun. es hat nur mit dem aktuell laufenden Prozess zu tun. Wenn der Kernel die Frage „Was bedeutet /proc/selfdas?“ Beantworten muss , wählt er einfach die aktuell geplante PID aus , dh den aktuell ausgeführten Prozess (auf der aktuellen logischen CPU). Der Effekt ist, dass /proc/selfimmer auf die PID des fragenden Programms zeigt. wenn du läufst

ls -l /proc/self

du siehst ls's PID, wenn du Code schreibst, der diesen Code verwendet /proc/self, siehst du seine eigene PID usw.

Stephen Kitt
quelle
13
Dies ist in gewissem Sinne "genau", aber für jemanden, der das Kernel-Konzept von "aktuell" nicht versteht, nicht von Bedeutung. Eine bessere Antwort wäre, dass es der Prozess ist das System Anruf mit /proc/selfals Teil des Pfadnamens in einem seiner Argumente.
R ..
1
@R .. das ist, was ilkkachus Antwort hervorhebt, zögern Sie nicht, diese zu unterstützen - das habe ich getan.
Stephen Kitt
36

Derjenige, der auf den Symlink zugreift (ruft readlink () auf oder open () auf einem Pfad durch ihn). Es würde zu der Zeit auf der CPU laufen, aber das ist nicht relevant. Ein Multiprozessorsystem kann mehrere Prozesse gleichzeitig auf der CPU haben.

Vordergrund- und Hintergrundprozesse sind meistens ein Shell-Konstrukt, und es gibt auch keinen eindeutigen Vordergrundprozess, da alle Shell-Sitzungen auf dem System einen haben.

ilkkachu
quelle
27

Die Formulierung hätte besser sein können, aber jede Formulierung, die Sie versuchen, um die Idee der Selbstreferenz auszudrücken, wird verwirrend sein. Der Name des Verzeichnisses ist meiner Meinung nach aussagekräftiger.

Stellt im Grunde /proc/self/den Prozess dar, der liest /proc/self/. Wenn Sie also versuchen, /proc/self/ein C-Programm zu öffnen , repräsentiert es dieses Programm. Wenn Sie versuchen, es von der Shell aus zu tun, dann ist es die Shell usw.

Aber was ist, wenn Sie eine Quad-Core-CPU haben, die in der Lage ist, 4 Prozesse gleichzeitig auszuführen, also kein Multitasking?

Dann wird jeder Prozess einen anderen sehen, /proc/self/ohne dass man sich gegenseitig sehen kann /proc/self/.

Wie funktioniert das?

Naja, /proc/self/ist eigentlich kein Ordner. Es ist ein Gerätetreiber, der sich zufällig als Ordner ausgibt, wenn Sie versuchen, darauf zuzugreifen. Dies liegt daran, dass die für Ordner erforderliche API implementiert wird. Das /proc/self/Verzeichnis ist nicht das einzige, das dies tut. Ziehen Sie freigegebene Ordner in Betracht, die von Remoteservern bereitgestellt wurden, oder aktivieren Sie USB-Sticks oder Dropbox. Sie alle implementieren dieselben APIs, mit denen sie sich wie Ordner verhalten.

Wenn ein Prozess versucht, auf /proc/self/den Gerätetreiber zuzugreifen , werden seine Inhalte dynamisch generiert, indem Daten aus diesem Prozess gelesen werden. Die Dateien in existieren /proc/self/also nicht wirklich. Es ist wie ein Spiegel, der den Prozess reflektiert, der versucht, ihn zu betrachten.

Ist es wirklich ein Gerätetreiber? Du hörst dich an, als ob du Dinge zu stark vereinfachst!

Ja, das ist es wirklich. Wenn Sie pedantisch sein wollen, ist es ein Kernel-Modul. Wenn Sie jedoch Usenet-Posts auf den verschiedenen Linux-Entwicklerkanälen lesen, verwenden die meisten Kernel-Entwickler "Gerätetreiber" und "Kernel-Modul" austauschbar. Früher habe ich Gerätetreiber, fehlerhafte Kernelmodule für Linux geschrieben. Wenn Sie eine eigene Benutzeroberfläche erstellen möchten, /proc/beispielsweise ein /proc/unix.stackexchange/Dateisystem, das Beiträge von dieser Website zurückgibt, können Sie in dem von O'Reilly veröffentlichten Buch "Linux Device Drivers" nachlesen, wie dies funktioniert. Es ist sogar als Softcopy online verfügbar.

Slebetman
quelle
6
/proc/selfist kein Gerätetreiber, sondern Teil eines kernelexponierten Dateisystems procfs.
Chris Down
1
@ChrisDown: Ja, aber es ist als Kernel-Modul implementiert - das ist die Linux-Version des Gerätetreibers - es gibt sogar ein Beispiel für die Implementierung eines /procbasierten Treibers im ehrwürdigen Buch "Linux Device Drivers". Ich sollte wissen, ich habe eine im College implementiert. Ich hätte wahrscheinlich stattdessen den Begriff "Kernelmodul" verwenden können, aber "Gerätetreiber" ist das, was die meisten Leute kennen, und ich möchte nicht den irreführenden Eindruck erwecken, dass es einen signifikanten Unterschied zwischen "Kernelmodul" und "Gerätetreiber" gibt. abgesehen von der Terminologie.
Slebetman
7
@slebetman Nun, procfs ist kein Modul an sich, es kann nur eingebaut werden, niemals als Modul. Wenn Sie Haare teilen möchten, ist das Haar zu teilen, dass es ein Dateisystemtreiber ist, kein Gerätetreiber
hobbs
10

Es ist der Prozess, auf den zugegriffen wird, /proc/selfoder die darin enthaltenen Dateien / Ordner.

Versuchen Sie es cat /proc/self/cmdline. Überraschenderweise erhalten Sie cat /proc/self/cmdline(tatsächlich wird anstelle eines Leerzeichens ein Nullzeichen zwischen dem tund dem /angezeigt), da dies der Cat-Prozess ist, der auf dieses Pseudofile zugreift.

Wenn Sie eine ls -l /proc/selfausführen, wird die PID des ls-Prozesses selbst angezeigt. Oder wie wäre es ls -l /proc/self/exe; es wird auf die ausführbare Datei von ls verweisen.

Oder probieren Sie dies zur Abwechslung:

$ cp /proc/self/cmdline /tmp/cmd
$ hexdump -C /tmp/cmd
00000000  63 70 00 2f 70 72 6f 63  2f 73 65 6c 66 2f 63 6d  |cp./proc/self/cm|
00000010  64 6c 69 6e 65 00 2f 74  6d 70 2f 63 6d 64 00     |dline./tmp/cmd.|
0000001f

oder auch

$ hexdump -C /proc/self/cmdline 
00000000  68 65 78 64 75 6d 70 00  2d 43 00 2f 70 72 6f 63  |hexdump.-C./proc|
00000010  2f 73 65 6c 66 2f 63 6d  64 6c 69 6e 65 00        |/self/cmdline.|
0000001e

Wie gesagt, es ist der Prozess, auf den zugegriffen wird, /proc/selfoder die darin enthaltenen Dateien / Ordner.

Viktor Toth
quelle
2

/ proc / self ist syntaktischer Zucker. Es ist eine Verknüpfung zur Verkettung von / proc / und dem Ergebnis des Systemaufrufs getpid () (in bash als Metavariable $$ verfügbar). Es kann verwirrend werden, wenn bei Shell-Skripten viele der Anweisungen andere Prozesse aufrufen, einschließlich der eigenen PIDs ... PIDs, die häufig auf tote Prozesse verweisen. Erwägen:

root@vps01:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 Jan  1 01:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan  1 01:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan  1 01:51 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jan  1 01:51 3 -> /proc/26562/fd
root@vps01:~# echo $$
593

'/ bin / ls' wertet den Pfad zum Verzeichnis aus und löst ihn als / proc / 26563 auf, da dies die PID des Prozesses ist - der neu erstellte Prozess / bin / ls -, der den Inhalt des Verzeichnisses liest. Bis zum nächsten Prozess in der Pipeline, im Fall von Shell-Skripten oder zum Zeitpunkt der Rückkehr der Eingabeaufforderung, im Fall einer interaktiven Shell, ist der Pfad jedoch nicht mehr vorhanden und die Informationsausgabe bezieht sich auf einen nicht vorhandenen Prozess.

Dies gilt jedoch nur für externe Befehle (dh ausführbare Programmdateien, die nicht in die Shell selbst integriert sind). Sie erhalten also andere Ergebnisse, wenn Sie beispielsweise Dateinamen-Globbing verwenden, um eine Liste des Inhalts des Verzeichnisses zu erhalten, anstatt den Pfadnamen an den externen Prozess / bin / ls zu übergeben:

root@vps01:~# ls /proc/self/fd
0  1  2  3
root@vps01:~/specs# echo /proc/self/fd/*
/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3

In der ersten Zeile hat die Shell über exec () syscall einen neuen Prozess '/ bin / ls' erzeugt, wobei "/ proc / self / fd" als argv [1] übergeben wurde. '/ bin / ls' öffnete seinerseits das Verzeichnis / proc / self / fd und las dessen Inhalt, dann druckte er ihn aus, während er darüber iterierte.

In der zweiten Zeile wird jedoch glob () hinter den Kulissen verwendet, um die Liste der Dateinamen zu erweitern. Diese werden als Array von Zeichenfolgen zum Echo übergeben. (Wird normalerweise als interner Befehl implementiert, aber es gibt oft auch einen / bin / echo-Binärbefehl ... aber dieser Teil ist eigentlich irrelevant, da sich echo nur mit Strings befasst und niemals mit einem Systemaufruf in Verbindung mit Pfadnamen verbunden ist.)

Betrachten Sie nun den folgenden Fall:

root@vps01:~# cd /proc/self/fd
root@vps01:~# ls
0  1  2  255

Hier hat die Shell, der übergeordnete Prozess von / bin / ls, ein Unterverzeichnis von / proc / self zu ihrem aktuellen Verzeichnis gemacht . Somit werden relative Pfadnamen aus ihrer Perspektive ausgewertet. Ich vermute, dass dies mit der POSIX-Dateisemantik zusammenhängt, bei der Sie mehrere feste Links zu einer Datei erstellen können, einschließlich aller geöffneten Dateideskriptoren. Diesmal verhält sich / bin / ls also ähnlich wie echo / proc / $$ / fd / *.

Barry J. Burns
quelle
-2

Wenn die Shell Programme wie ls in separaten Prozessen aufruft, wird / proc / self als Symlink zu nnnnn angezeigt , wobei nnnnn die Prozess-ID des ls-Prozesses ist. Soweit ich weiß, sind häufig verwendete Shells nicht zum Lesen von Symlinks integriert, aber Perl hat:

perl -e 'print "/ proc / self link:", readlink ("/ proc / self"), "- pid $$ \ n";'

/ Proc / self verhält sich also wie ein Symlink, aber das procfs-Dateisystem macht es "magisch" prozessbewusst.

LHP
quelle