Damit nun auf dem Linux-System kein Chaos entsteht, wenn viele hunderte User gleichzeitig die Maschine benutzen, müssen die einzelnen gestartetet Programme sauber voneinander getrennt werden.
Jedes auf einem Linux gestartete Programm ist ein sogenannter Prozess. Er erhält dazu eine eindeutige Prozessnummer PID und eine eigene Arbeitsumgebung (Environment) zugewiesen, die er nutzen kann. Die Arbeitsumgebung enthält z.B. wichtige Umgebungsvariablen, virtuelle Gerätedateien u.v.a.m. Diese Arbeitsumgebung wird jedem Prozess von dem Prozess eingerichtet und zugewiesen, von dem er gestartet wurde. Wenn man in einer interaktiven Shell an einem Terminal arbeitet und ein Kommando startet, dann erzeugt die aufrufende Shell diese Arbeitsumgebung für das Kommando. Es handelt sich damit um einen Kindprozess der Shell. Im Wesentlichen ist diese Arbeitsumgebung eine Kopie der Arbeitsumgebung (Environment) des aufrufenden Prozesses, in diesem Fall also der Shell, die auf den Kindprozess angepasst und z.B. durch Datenstromumleitungen verändert wurde.
Wenn einer oder mehrere Prozesse nur durch einen anderen Prozess gestartet werden können, wo kommt dann der erste Prozess her?
Den Start des ersten Prozesses übernimmt der Kernel des Systems nach dem Bootvorgang.
Wenn der Kernel gestartet ist, ruft er den Urprozess init auf.
Dieser Urprozess liest seine Konfigurationsdatei /etc/inittab ein und startet danach alle anderen Prozesse.
In der Datei /etc/inittab ist unter anderem eingetragen, welche virtuellen und seriellen Terminals benutzt werden sollen und welche Scripte den weiteren Systemstart durchführen sollen.
Letztendlich ist also jeder Prozess ein Kindprozess von init.
Mit den folgenden Kommandos bekommt man sehr schnell eine Übersicht über die laufenden Prozesse:
Ausgabe von top | Ausgabe von ps | Ausgabe von pstree |
Tasks: 147 total, 1 running, 146 sleeping, 0 stopped, 0 zombie Cpu(s): 36.8%us, 30.3%sy, 0.0%ni, 32.3%id, 0.3%wa, 0.0%hi, 0.3%si, 0.0%st Mem: 1537180k total, 549500k used, 987680k free, 47928k buffers Swap: 1959924k total, 0k used, 1959924k free, 326244k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3288 frank 20 0 2652 1084 808 R 2.0 0.1 0:00.01 top 1 root 20 0 824 276 236 S 0.0 0.0 0:01.39 init 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 0:03.05 ksoftirqd/0 4 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0 6 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 7 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 cpuset 8 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 khelper 9 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/u:1 12 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns 274 root 20 0 0 0 0 S 0.0 0.0 0:00.02 sync_supers 276 root 20 0 0 0 0 S 0.0 0.0 0:00.00 bdi-default 278 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kblockd 280 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kacpid 281 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kacpi_notify 282 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kacpi_hotplug 358 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 ata_sff bash-4.1$ |
bash-4.1$ ps PID TTY TIME CMD 2667 pts/1 00:00:00 bash 3370 pts/1 00:00:00 ps bash-4.1$ |
bash-4.1$ pstree init-+-acpid |-6*[agetty] |-applet.py |-atd |-console-kit-dae---64*[{console-kit-da}] |-crond |-cupsd |-2*[dbus-daemon] |-dbus-launch |-dhcpcd |-gam_server |-geany-+-bash | |-gnome-pty-helpe | `-{geany} |-gpm |-hald-+-hald-runner-+-hald-addon-acpi | | |-hald-addon-inpu | | `-4*[hald-addon-stor] | `-{hald} |-httpd---10*[httpd] |-inetd |-kdm-+-X | |-kdm---sh-+-xfce4-session-+-Thunar | | | |-xfce4-panel-+-xfce4-menu-plug | | | | |-xfce4-mixer-plu---{xfce4-+ | | | | |-xterm---bash---pstree | | | | |-xterm---bash | | | | `-{xfce4-panel} | | | |-xfdesktop | | | |-xfwm4 | | | `-{xfce4-session} | | `-xscreensaver | `-kdm---kdm_greet---{kdm_greet} |-klogd |-mount.ntfs-3g |-obex-data-serve |-polkit-gnome-au---{polkit-gnome-a} |-polkitd---{polkitd} |-ssh-agent |-sshd |-syslogd |-udevd---2*[udevd] |-xfce4-power-man |-xfce4-settings- |-xfconfd `-xfsettingsd bash-4.1$ |
Schaut man sich die Ausgabe von ps genauer an, dann erkennt man, das zwei Prozesse auf dem System von mir ausgelöst wurden.
bash-4.1$ ps PID TTY TIME CMD 2667 pts/1 00:00:00 bash 3370 pts/1 00:00:00 ps bash-4.1$
Die bash mit der PID 2667 und das Kommando ps mit der PID 3370.
Der Kernel erzeugt zu allen Geräten eine Datei-Schnittstelle, auch zu sich selbst. Diese Dateistruktur bildet die Schnittstelle zum Kernel. Hier wird ein Abbild des Kernels aus der Sicht des darauf zugreifenden Prozesses gezeigt. Die Inhalte sind also dynamisch und ändern sich von Prozess zu Prozess.
bash-4.1$ ls /proc 1 1288 1518 1917 1991 2098 2358 3 372 616 833 cmdline iomem meminfo stat 1000 1314 1522 1919 1992 2099 2631 3266 4 617 847 config.gz ioports misc swaps 1012 1431 1597 1920 1993 2101 2634 3308 476 618 854 cpuinfo irq modules sys 1018 1475 1676 1921 1995 2102 2642 3310 477 621 855 crypto kallsyms mounts sysrq-trigger 1078 1476 1686 1946 2 2103 2643 3366 499 622 856 devices kcore mpt sysvipc 1081 1477 1691 1951 2045 2114 2644 3392 500 625 859 diskstats key-users mtrr timer_list 1084 1478 1698 1953 2060 2116 2665 3434 570 631 9 dma keys net timer_stats 1126 1479 1710 1966 2079 2123 2667 3466 572 632 993 driver kmsg pagetypeinfo tty 1128 1480 1713 1983 2082 2125 274 3566 595 637 996 execdomains kpagecount partitions uptime 1141 1481 1782 1985 2087 2127 276 3577 6 639 acpi fb kpageflags sched_debug version 1142 1482 1787 1987 2088 2128 278 358 607 680 asound filesystems loadavg scsi vmallocinfo 1172 1485 1855 1988 2090 2140 280 3598 608 7 buddyinfo fs locks self vmstat 12 1486 1887 1989 2092 2230 281 366 609 8 bus i2o mdstat slabinfo zoneinfo 1278 1487 1909 1990 2096 2312 282 369 615 828 cgroups interrupts megaraid softirqs bash-4.1$
Hier fallen einem sofort die vielen Unterverzeichnisse auf, deren Name nur eine Nummer ist.
Bei diesen Nummern handelt es sich um die Prozessnummern der einzelnen Prozesse, die momentan auf dem System laufen.
In diesen Verzeichnissen kann man sich nun die Arbeitsumgebung der Prozesse anschauen, wenn man die Rechte dazu besitzt.
In der Liste ist das Verzeichnis 2667 zu sehen, das gehört also zu meiner bash.
Ein Verzeichnis 3370 für das von mir gestartete ps existiert jedoch nicht.
Das ist auch logisch, denn der Prozess läuft nun nicht mehr und deshalb wurde die Arbeitsumgebung des Prozesses vernichtet.
Im Verzeichnis /proc/2667/ finden sich nun weitere Unterverzeichnisse und Dateien, die die Arbeitsumgebung des bash-Prozesses wiederspiegeln.
bash-4.1$ ls /proc/2667/ attr clear_refs coredump_filter environ fdinfo loginuid mountinfo net oom_score_adj root smaps statm task auxv cmdline cpuset exe io maps mounts oom_adj pagemap sched stack status wchan cgroup comm cwd fd limits mem mountstats oom_score personality sessionid stat syscall bash-4.1$
Eine Besonderheit (naja, eigentlich nicht) ist das Verzeichnis /proc/self. Dabei handelt es sich um einen symbolischen Link in das Verzeichnis des zugreifenden Prozesses. Wenn also die bash auf /proc/self zugreift, dann landet sie im Verzeichnis /proc/2667. Wenn das Kommando ps das getan hat, als es noch lief, dann führte das Verzeichnis /proc/self für diesen Prozess in das Verzeichnis /proc/3370.
Ein weiteres wichtiges Verzeichnis ist /dev. Hier handelt es sich ebenfalls um ein Kernelabbild. Man findet hier wieder eine große Anzahl von Dateien und Unterverzeichnissen. Hierbei handelt es sich ebenfalls um Pseudodateien, die alle Geräte (echte oder virtuelle), die der Kernel mit seinen Treibern unterstützt als Datei ab. Über diese Gerätedateien erhält das System den Zugriff auf die angeschlossene Hardware.