2013-02-09 4 views
22

Also zwei Fragen hier wirklich. Erstens, (und ja, ich habe das bereits gesucht, wollte aber klarstellen), was ist der Unterschied zwischen einem Benutzer-Thread und einem Kernel-Thread? Ist es einfach, dass eines von einem Benutzerprogramm und das andere von einem Betriebssystem generiert wird, wobei letzteres Zugriff auf privilegierte Anweisungen hat? Sind sie konzeptionell gleich oder gibt es tatsächlich Unterschiede in den Threads? Das zweite Problem, das ich habe, lautet: Das Buch, das ich verwende, sagt, dass "eine Beziehung zwischen Benutzer- und Kernel-Threads bestehen muss", um die verschiedenen Modelle einer solchen Beziehung aufzulisten. Aber das Buch erklärt nicht klar , warum ein Benutzer-Thread muss immer zu einem bestimmten Kernel-Thread zugeordnet werden. Warum ist das?Threads: Warum müssen alle Benutzer-Threads einem Kernel-Thread zugeordnet sein?

Antwort

22

Ein Kernel-Thread ist ein Thread-Objekt, das vom Betriebssystem verwaltet wird. Es ist ein tatsächlicher Thread, der vom Prozessor geplant und ausgeführt werden kann. Systemthreads sind in der Regel schwergewichtige Objekte mit Berechtigungseinstellungen, Prioritäten usw. Der Kernel-Thread-Scheduler ist für die Planung von Kernel-Threads zuständig.

Benutzerprogramme können auch eigene Thread-Scheduler erstellen. Sie können ihre eigenen "Threads" erstellen und Kontext-Schalter simulieren, um zwischen ihnen zu wechseln. Diese Threads sind jedoch keine Kernel-Threads. Jeder Benutzer-Thread kann nicht wirklich alleine ausgeführt werden, und die einzige Möglichkeit für einen Benutzer-Thread ist es, wenn ein Kernel-Thread tatsächlich aufgefordert wird, den in einem Benutzer-Thread enthaltenen Code auszuführen. Nichtsdestoweniger haben Benutzer-Threads große Vorteile gegenüber Kernel-Threads. Sie können viel leichter sein, da sie nicht unbedingt ihre eigenen Prioritäten haben müssen, können von einem einzigen Prozess verwaltet werden (der möglicherweise bessere Informationen darüber hat, welche Threads wann ausgeführt werden müssen) und nicht viele erstellen Kernel-Objekte zum Zwecke der Sicherheit und Sperrung.

Der Grund, dass Benutzer-Threads Kernel-Threads zugeordnet werden müssen, ist, dass ein Benutzer-Thread nur ein Haufen Daten in einem Benutzerprogramm ist. Kernel-Threads sind die echten Threads im System. Damit ein Benutzer-Thread Fortschritte machen kann, muss der Scheduler des Benutzerprogramms einen Benutzer-Thread nehmen und ihn dann auf einem Kernel-Thread ausführen. Die Zuordnung zwischen Benutzer- und Kernel-Threads muss nicht eins zu eins sein (1: 1); Sie können mehrere Benutzer-Threads für denselben Kernel-Thread verwenden (es kann jeweils nur einer dieser Benutzer-Threads ausgeführt werden), und Sie können einen einzelnen Benutzer-Thread verwenden, der über verschiedene Kernel-Threads in einem 1: n-Mapping rotiert.

1

Ich denke, ein Beispiel aus der realen Welt wird die Verwirrung klären, also lasst uns sehen, wie die Dinge in Linux erledigt werden.

Zunächst unterscheidet Linux nicht zwischen Prozess und Thread, die planbare Entität heißt Task in Linux und wird durch task_struct repräsentiert. Wenn Sie also einen Systemaufruf fork() ausführen, wird ein neues task_struct erstellt, das Daten (oder Zeiger) enthält, die mit neuen Tasks verknüpft sind.

So bedeutet in der Linux-Welt ein Kernel-Thread ein task_struct-Objekt (Struktur). Weil der Scheduler nur über diese Entitäten weiß, die verschiedenen CPUs zugeordnet werden können (logisch oder physikalisch). Mit anderen Worten, wenn der Linux Scheduler Ihren Prozess planen soll, müssen Sie ein task_struct erstellen.

Benutzer-Thread ist etwas, das außerhalb des Kernels von einer Ausführungsumgebung (EE von jetzt an) wie JVM unterstützt und verwaltet wird. Diese EEs bieten Ihnen einige Funktionen zum Erstellen neuer Threads.

Lassen Sie uns jetzt Ihre Frage beantworten

why a user thread must always be mapped to a specific kernel thread. 

Lasst uns sagen, dass Sie einige Threads erstellt Ihre EE verwenden.eventuell müssen sie von der CPU ausgeführt werden und von oben her wissen wir, dass Sie (thread) ein task_struct haben müssen, um einer CPU zugewiesen zu werden. Deshalb muss das Mapping existieren. Es ist die Pflicht Ihres EE, task_struct zu erstellen.

Wenn Ihr EE viele zu einem Modell verwendet, dann erstellt es nur ein task_struct für alle Threads und plant alle diese Threads auf dieses task_struct. Stellen Sie sich vor, es gibt eine CPU (task_struct) und viele Prozesse (Threads, die in EE erstellt wurden), Ihr Betriebssystem (EE) multiplext diese Prozesse auf dieser einzelnen CPU.

Wenn ein Eins-zu-Eins-Modell verwendet wird, dann gibt es für jedes in EE erstellte Thread ein task_struct. Wenn Sie also einen neuen Thread in Ihrem EE erstellen, wird das entsprechende task_struct im Kernel erstellt.

Windows macht Dinge anders (Prozess und Thread ist unterschiedlich), aber die allgemeine Idee bleibt gleich, dass Kernel Thread die Entität ist, die CPU Scheduler für die Zuweisung berücksichtigt, daher müssen Benutzer Threads entsprechenden Kernel-Threads zugeordnet werden (wenn Sie CPU wollen richtet sie hin).

Verwandte Themen