Gibt es eine Beziehung zwischen einem kernel und einen Anwender-thread?
Einige Betriebssystem Schulbücher sagte, dass "Karten eine (viele) user-thread auf einem (vielen) kernel-thread". Was bedeutet Karte bedeutet hier?
InformationsquelleAutor der Frage Pwn | 2009-07-24
Wenn Sie sagen, anzeigen, bedeuten Sie, dass jeder kernel thread zugeordnet ist, eine bestimmte Anzahl von user-mode threads.
Kernel-threads werden verwendet, um privilegierte Dienste für Anwendungen (wie system-calls ). Sie werden auch verwendet durch den kernel zu verfolgen, was alles auf dem system ausgeführt wird, wie viel von welchen Ressourcen bereitgestellt werden, um was für einen Prozess, und um diese zu planen.
Wenn Ihre Anwendungen machen starken Gebrauch von system calls, mehr user threads pro kernel-thread, und in Ihren Anwendungen werden langsamer ausgeführt. Dies ist, weil der kernel-thread wird ein Engpass, da alle system-calls durch Sie hindurch.
Auf der anderen Seite aber, wenn Ihre Programme nur selten verwenden Sie die system-Aufrufe (oder andere kernel-Diensten), können Sie eine große Anzahl von Benutzer-threads kernel Threads ohne viel Leistungseinbußen, andere als overhead.
Erhöhen Sie die Anzahl der kernel-threads, aber diese fügt zusätzlichen Aufwand für den kernel im Allgemeinen, so dass während der einzelnen Themen wird stärker mit Bezug auf system fordert, das ganze system wird langsamer.
Deshalb ist es wichtig, Sie zu finden eine gute balance zwischen der Anzahl der kernel-threads und die Anzahl der Benutzer-threads pro kernel-thread.
InformationsquelleAutor der Antwort samoz
http://www.informit.com/articles/printerfriendly.aspx?p=25075
Implementierung von Threads im User-Space
Gibt es zwei Möglichkeiten für die Implementierung eines threads, Paket: im user-space und im kernel. Die Auswahl ist mäßig umstritten, und eine hybrid-Implementierung ist ebenfalls möglich. Wir werden nun beschreiben Sie diese Methoden zusammen mit Ihren vor-und Nachteilen.
Die erste Methode ist, das threads-package vollständig im user-space. Der kernel weiß nichts über Sie. Soweit der kernel betroffen ist, ist es der Verwaltung normalen, single-threaded Prozesse. Der erste und offensichtlichste Vorteil ist, dass ein user-level threads Paket umgesetzt werden kann, auf ein Betriebssystem, das unterstützt keine threads. Allen Betriebssystemen verwendet zu werden, fallen in diese Kategorie, und auch nun, einige tun es noch immer.
Alle diese Implementierungen haben die gleichen Allgemeinen Struktur, die in Abb. 2-8 a). Die Fäden laufen auf der Oberseite des run-time-system, das eine Sammlung von Verfahren, verwalten von threads. Wir haben gesehen, vier davon schon: thread_create, thread_exit, thread_wait, und thread_yield, aber in der Regel gibt es mehr.
Wenn die threads verwaltet werden, die im user-space, die jeder Prozess benötigt seine eigene private thread-Tabelle, um zu verfolgen die threads in diesem Prozess. Diese Tabelle ist Analog zu den kernel-Prozess-Tabelle, außer dass es hält verfolgen nur die pro-thread-Eigenschaften wie die einzelnen thread ' s program counter, stack pointer, Register, Zustand, etc.. Die thread-Tabelle verwaltet wird von der run-time-system. Wenn ein thread verschoben wird in den bereit-Zustand oder sperrzustand über, die Informationen, die benötigt werden um es neu zu starten ist gespeichert in der thread-Tabelle, die genau der gleichen Art und Weise wie der kernel speichert Informationen über Prozesse in der Prozess-Tabelle.
Wenn ein thread etwas tut, kann es verursachen, blockiert werden lokal, zum Beispiel, wartet für einen anderen thread im Prozess um eine Arbeit, es fordert eine run-time-system Verfahren. Dieses Verfahren überprüft, um zu sehen, ob der thread muss in gesperrten Zustand. Wenn dem so ist, speichert es die thread ' s Register (d.h., seine eigenen) in der thread-Tabelle, schaut in der Tabelle für einen thread laufen, und entlädt die Maschine registriert mit der neuen thread-die gespeicherten Werte. Sobald der stack-Zeiger und Programmzähler gewechselt wurden, der neue thread kommt wieder zum Leben automatisch. Wenn die Maschine hat eine Anweisung zum speichern aller Register und eine andere, um diese zu laden, wird der gesamte thread wechseln kann man in einer Handvoll von Anweisungen. Tut thread-switching wie das ist mindestens eine Größenordnung schneller als die überfüllung auf der kernel-und der ist ein starkes argument zu Gunsten der user-level-threads-Pakete.
Allerdings gibt es einen entscheidenden Unterschied: die Prozesse. Wenn ein thread fertig ist, läuft für den moment, zum Beispiel, wenn er ruft thread_yield, den code von thread_yield können speichern der thread-information in der thread-Tabelle selbst. Darüber hinaus kann es danach rufen Sie den thread-scheduler zu Holen einem anderen thread ausgeführt werden. Die Prozedur, spart der thread Staates und der scheduler sind nur die lokalen Prozeduren so aufrufen, Sie ist viel effizienter als ein kernel-Aufruf. Unter anderem wird in keine Falle erforderlich ist, wird kein Kontextwechsel notwendig ist, kann der cache-Speicher müssen nicht gespült werden, und so weiter. Das macht die thread-scheduling sehr schnell.
User-level-threads haben auch andere Vorteile. Sie erlauben es jedem Prozess seine eigene scheduling-Algorithmus. Für einige Anwendungen, zum Beispiel solche mit einem garbage-collector-thread, nicht sorgen darüber zu machen, ein thread gestoppt werden zu einem ungünstigen moment, ist ein plus. Sie skalieren auch besser, da kernel-threads ausnahmslos erfordern einigen Platz auf dem Tisch und stack-space in den kernel, was zu einem problem werden kann, wenn es gibt eine sehr große Anzahl von threads.
Trotz Ihrer besseren performance, user-level-threads-Pakete haben einige große Probleme. Erste unter diesen ist das problem, wie blockierende Systemaufrufe implementiert sind. Angenommen, ein thread liest von der Tastatur, bevor Sie irgendwelche Tasten getroffen wurden. Die Vermietung der thread eigentlich machen die system-call ist unannehmbar, da dies wird stop-alle threads. Eines der wichtigsten Ziele, dass threads in den ersten Platz gab, damit jeder Sie benutzen blockierende Aufrufe, aber um zu verhindern, dass ein thread blockiert wird, nicht auf die anderen. Mit blockierenden Systemaufrufen, es ist schwer zu sehen, wie dieses Ziel erreicht werden kann leicht.
Ruft das system konnte alle geändert werden, um nicht blockierende (z.B., Lesen Sie auf der Tastatur würde nur wieder 0 Byte, wenn keine Zeichen waren schon gepuffert), sondern erfordert änderungen an der Betriebssystem unattraktiv ist. Außerdem eines der Argumente für user-level-threads war ja gerade, dass Sie laufen konnte mit bestehenden Betriebssystemen. Darüber hinaus ändern die Semantik gelesen werden, werden änderungen erforderlich, um viele user-Programme.
Andere alternative ist es möglich in dem Fall, dass es möglich ist, zu sagen, im Voraus, wenn Sie einen Anruf zu blockieren. In einigen Versionen von UNIX, einem system-call, select vorhanden ist, was erlaubt, die Anrufer zu sagen, ob eine prospektive Lesen blockiert werden. Wenn dieser Anruf vorhanden ist, wird die Bibliothek Prozedur gelesen werden kann durch eine neue ersetzt, die zuerst macht einen Anruf auszuwählen, und dann tut nur das Lesen nennen, wenn es sicher ist (d.h., nicht-block). Wenn der read-Aufruf blockiert, wird der Anruf nicht gemacht. Stattdessen einem anderen thread ausgeführt wird. Das nächste mal die run-time-system erhält die Kontrolle, es kann noch einmal überprüfen, um zu sehen, wenn Sie das Lesen, ist jetzt sicher. Dieser Ansatz erfordert umschreiben Teile der system call library, ist ineffizient und unelegant, aber es gibt wenig Auswahl. Der code rund um den system-call, der das prüfen wird aufgerufen, eine Jacke oder einen wrapper.
Etwas Analog zu dem problem der blocking-system fordert, ist das problem der Seitenfehler. Wir werden diese Studie in Kap. 4. Für den moment ist es ausreichend zu sagen, dass Computer kann eingerichtet sein so, dass nicht alles, das Programm ist im Hauptspeicher, auf einmal. Wenn das Programm fordert, oder springt auf eine Anweisung, die nicht im Speicher ist, wird ein Seitenfehler tritt auf, und das Betriebssystem gehen und sich die fehlende Anleitung (und seine Nachbarn) von der Festplatte. Dies nennt man einen page fault. Der Prozess ist blockiert, während der Belehrung notwendig ist, sich und Lesen Sie. Wenn ein thread bewirkt, dass ein page fault, der kernel, nicht einmal zu wissen, über die Existenz des threads, der natürlich blockiert den gesamten Prozess, bis die disk-I/O abgeschlossen ist, auch wenn andere threads könnte lauffähig.
Ein weiteres problem mit user-level-thread-Pakete ist, dass wenn ein thread gestartet wird, kein anderer thread in diesem Prozess wird immer ausgeführt, wenn der erste thread freiwillig die CPU. In einem einzelnen Prozess, es gibt keine Uhr-interrupts, der es unmöglich macht, zu planen-Prozesse, round-robin-Weise (abwechselnd). Wenn ein thread in den run-time-system von seiner eigenen freien Willen, der scheduler wird nie eine chance bekommen.
Eine mögliche Lösung für das problem des threads läuft ewig ist die run-time-system-request-clock-signal (interrupt) an, sobald eine zweite zu geben, die es kontrollieren, aber das ist auch grob und chaotisch zu Programmieren. Periodic clock-interrupts mit einer höheren Frequenz sind nicht immer möglich, und selbst wenn Sie es sind, die total Aufwand kann erheblich sein. Außerdem ein thread, benötigt eventuell auch einen Uhr-interrupt, sich mit der run-time-system ist die Nutzung der Uhr.
Andere, und wohl die meisten vernichtende argument gegen user-level-threads ist, dass Programmierer in der Regel, dass threads, die genau in Anwendungen, wo die threads blockieren sich oft, wie, zum Beispiel, in einem Multithreading-fähigen Web-server. Diese threads werden ständig system-Aufrufe. Sobald ein trap aufgetreten ist, um den kernel für die Durchführung der system-call, es ist kaum mehr Arbeit für die kernel-threads zu wechseln, wenn der alte gesperrt wurde, und der kernel dadurch entfällt die Notwendigkeit, ständig wählen Sie system fordert Sie, dass der check um zu sehen, ob Lesen system-calls sind sicher. Für Anwendungen, die im wesentlichen vollständig CPU-bound und selten block, was ist der Sinn des threads? Niemand würde ernsthaft vorschlagen, die Berechnung der ersten n Primzahlen oder Schach spielen, die Verwendung von threads, weil es ist nichts damit gewonnen, wenn Sie es dieser Weg tun.
InformationsquelleAutor der Antwort
Benutzer-threads verwaltet werden, in userspace - das bedeutet Planung, Schaltung, etc. nicht aus dem kernel.
Seit, letztlich, der OS-kernel ist verantwortlich für Kontext-switching zwischen "execution units" - Ihre Benutzer-threads verknüpft werden müssen (dh., "Karte") eine kernel-planbare Objekt - ein kernel-thread[+1].
So, da N user-threads - man kann Sie nutzen N kernel-threads (1:1 anzeigen). , Können Sie die Vorteile der kernel, die hardware des multi-processing (Ausführung auf mehreren CPUs) und ein ziemlich simpel-Bibliothek - im Grunde nur aufzuschieben, die meisten von der Arbeit an dem kernel. Es macht jedoch Ihre app Portierbarkeit zwischen Betriebssystemen, da man nicht direkt den Aufruf der kernel-thread-Funktionen. Ich glaube, dass die POSIX-Threads (PThreads) ist die bevorzugte *nix-Umsetzung, und es folgt die 1:1 Karte (praktisch äquivalent zu einem kernel-thread). Das aber ist nicht garantiert, wie es sein würde, die Umsetzung abhängig (ein Hauptgrund für die Verwendung von PThreads wäre die Portabilität zwischen Kernel).
Oder, Sie könnte verwenden Sie nur 1 kernel thread. Das würde ermöglichen es Ihnen, auf nicht-multitasking-Betriebssystem ist, oder völlig verantwortlich für die Terminierung. Windows' User Mode Planen ist ein Beispiel für diese N:1 Karte.
Oder, Sie könnten die Karte, um eine beliebige Anzahl von kernel-threads - eine N:M map. Windows hat Faserndie es erlauben würde, Sie auf die Karte N Fasern zu M kernel-threads und kooperativ planen. Ein threadpool könnte auch ein Beispiel dafür - N-workitems für die M-threads.
[+1] Ein Prozess hat mindestens 1 kernel-thread, der die eigentliche Ausführung Einheit. Auch ein kernel-thread enthalten sein muss in einem Prozess. OS planen müssen die thread zu laufen - nicht der Prozess.
InformationsquelleAutor der Antwort Mark Brackett
InformationsquelleAutor der Antwort Chris Tsui
Laut Wikipedia und Oracleuser-level-threads die eigentlich in einer Ebene montiert auf kernel threads; nichtdass kernel-threads ausgeführt neben user-level-threads aber, dass, allgemein gesprochen, die nur Personendie tatsächlich ausgeführt werden, der vom Prozessor/Betriebssystem kernel-threads.
Angenommen, wir haben ein Programm mit 2 user-level-threads, die beide zugeordnet (D. H. vergeben), die den gleichen kernel thread. Manchmal, das kernel-thread läuft die erste user-level-thread (und es wird gesagt, dass derzeit dieser kernel thread zugeordnet ist, um das erste user-level-thread) und einige andere Zeiten, die der kernel-thread läuft die zweite user-level-thread. So wir sagen, wir haben zwei user-level-threads zugeordnet auf die gleiche kernel-thread.
Als Klärung:
Den Kern eines OS ist aufgerufen, seine kernelso dass die threads auf kernel-Ebene (d.h. die threads, die der kernel kennt und verwaltet) werden als kernel-threads, die Aufrufe der Betriebssystem-Kern für die Dienste können aufgerufen werden kernel-Aufrufe, und ... . Die einzige eindeutige Beziehung zwischen kernel Dinge ist, dass Sie eng mit dem OS-Kern, nichts mehr.
InformationsquelleAutor der Antwort Mohammad Amin Bandekhoda