Linus Torvalds (torvalds@cs.helsinki.fi)
Di, 6. August 1996, 12:47:31 +0300 (EET DST)
Nachrichten sortiert nach: [Datum] [Thread] [Betreff] [Autor]
Nächste Nachricht: Bernd P. Ziller: "Re: Ups in get_hash_table"
Vorherige Nachricht: Linus Torvalds: "Re: I / O Request Ordering"
Am Montag, 5. August 1996, schrieb Peter P. Eiserloh:
Wir müssen das Konzept der Fäden klar halten. Zu viele Leute scheinen einen Thread mit einem Prozess zu verwechseln. Die folgende Diskussion spiegelt nicht den aktuellen Stand von Linux wider, sondern ist ein Versuch, auf einer Diskussion auf hoher Ebene zu bleiben.
NEIN!
Es gibt keinen Grund zu der Annahme, dass "Threads" und "Prozesse" separate Einheiten sind. So wird es traditionell gemacht, aber ich persönlich halte es für einen großen Fehler, so zu denken. Der einzige Grund, so zu denken, ist historisches Gepäck.
Sowohl Threads als auch Prozesse sind wirklich nur eine Sache: ein "Kontext der Ausführung". Der Versuch, verschiedene Fälle künstlich zu unterscheiden, ist nur selbstlimitierend.
Ein "Kontext der Ausführung", hiermit COE genannt, ist nur das Konglomerat des gesamten Zustands dieses COE. Dieser Status umfasst Dinge wie den CPU-Status (Register usw.), den MMU-Status (Seitenzuordnungen), den Berechtigungsstatus (UID, GID) und verschiedene "Kommunikationszustände" (offene Dateien, Signalhandler usw.). Traditionell bestand der Unterschied zwischen einem "Thread" und einem "Prozess" hauptsächlich darin, dass ein Thread einen CPU-Status (+ möglicherweise einen anderen minimalen Status) hat, während der gesamte andere Kontext aus dem Prozess stammt. Dies ist jedoch nur
eine Möglichkeit, den Gesamtzustand des COE aufzuteilen, und nichts sagt aus, dass dies der richtige Weg ist. Sich auf diese Art von Bild zu beschränken, ist einfach nur dumm.
Die Art und Weise Linux darüber denkt (und die Art , wie ich die Dinge arbeiten will) ist , dass es ist nicht so etwas wie ein „Prozess“ oder „Faden“. Es gibt nur die Gesamtheit des COE (von Linux "Task" genannt). Verschiedene COEs können Teile ihres Kontexts miteinander teilen, und eine Teilmenge dieser Freigabe ist das traditionelle "Thread" / "Prozess" -Setup, aber das sollte wirklich als NUR eine Teilmenge angesehen werden (es ist eine wichtige Teilmenge, aber diese Bedeutung kommt nicht vom Design, sondern von Standards: Wir wollen offensichtlich auch standardkonforme Thread-Programme auf Linux ausführen.
Kurz gesagt: Entwerfen Sie NICHT um die Denkweise von Thread / Prozess. Der Kernel sollte nach der COE-Denkweise gestaltet sein, und dann kann die pthreads- Bibliothek die eingeschränkte pthreads-Schnittstelle an Benutzer exportieren, die diese Sichtweise auf COEs verwenden möchten.
Nur als Beispiel dafür, was möglich wird, wenn Sie COE im Gegensatz zu Thread / Prozess denken:
- Sie können ein externes "CD" -Programm erstellen, was unter UNIX und / oder Prozess / Thread traditionell unmöglich ist (dummes Beispiel, aber die Idee ist, dass Sie diese Art von "Modulen" haben können, die nicht auf das traditionelle UNIX beschränkt sind / threads setup). Machen Sie eine:
Klon (CLONE_VM | CLONE_FS);
Kind: execve ("external-cd");
/ * Das "execve ()" trennt die Zuordnung der VM. Der einzige Grund, warum wir CLONE_VM verwendet haben, bestand darin, das Klonen zu beschleunigen. * /
- Sie können "vfork ()" natürlich ausführen (es erfordert nur minimale Kernel-Unterstützung, aber diese Unterstützung passt perfekt zur CUA-Denkweise):
Klon (CLONE_VM);
Kind: weiter laufen, schließlich ausführen ()
Mutter: Warte auf die Ausführung
- Sie können externe "IO-Deamons" ausführen:
Klon (CLONE_FILES);
Kind: offene Dateideskriptoren usw.
mutter: benutze die fd's die das kind geöffnet hat und vv.
All dies funktioniert, weil Sie nicht an die Denkweise von Thread / Prozess gebunden sind. Stellen Sie sich zum Beispiel einen Webserver vor, auf dem die CGI-Skripte als "Ausführungsthreads" ausgeführt werden. Mit herkömmlichen Threads ist dies nicht möglich, da herkömmliche Threads immer den gesamten Adressraum gemeinsam nutzen müssen. Sie müssen also alles, was Sie jemals wollten, auf dem Webserver selbst verknüpfen (ein "Thread" kann nicht ausgeführt werden eine andere ausführbare Datei).
Das Denken an das als „Kontext der Ausführung“ Problems stattdessen können Ihre Aufgaben jetzt wählen externe Programme auszuführen (= den Adressraum von der Mutter zu trennen) usw. , wenn sie wollen, oder sie können zum Beispiel teilt alles mit der Mutter außer für die Dateideskriptoren (damit die Unter- "Threads" viele Dateien öffnen können, ohne dass sich die Eltern darum kümmern müssen: Sie werden automatisch geschlossen, wenn der Unter- "Thread" beendet wird, und es werden keine FDs im Eltern verwendet) .
Stellen Sie sich zum Beispiel ein "inetd" mit Gewinde vor. Sie möchten Fork + Exec mit geringem Overhead, also können Sie unter Linux anstelle eines "fork ()" ein Inetd mit mehreren Threads schreiben, bei dem jeder Thread nur mit CLONE_VM erstellt wird (Adressraum freigeben, aber keine Datei freigeben) Deskriptoren usw.). Dann kann das Kind ausführen, wenn es sich um einen externen Dienst handelt (z. B. rlogind) oder um einen der internen inetd-Dienste (echo, timeofday). In diesem Fall erledigt es einfach seine Sache und wird beendet.
Mit "thread" / "process" geht das nicht.
Linus