Informatik · Klasse 12 · aktualisiert
Thread in der Informatik einfach erklärt
Du lernst, was ein Thread ist, wie er sich vom Prozess unterscheidet und warum gemeinsam genutzte Daten Synchronisation brauchen.
0 von 9 Aufgaben gelöst
Kurz gesagt
Ein Thread ist ein Ausführungsstrang innerhalb eines Prozesses. Jeder Thread hat einen eigenen Threadkontext, teilt sich aber Speicher und andere Ressourcen mit den übrigen Threads. Bei gemeinsam genutzten Daten kann es Konflikte geben, die man mit Synchronisation auflöst.
Dein Programm zeigt eine Oberfläche, wartet auf deine Eingabe und arbeitet nebenbei im Hintergrund. Dafür kann es mehrere Abläufe gleichzeitig verwalten. Diese Abläufe heißen Threads. Hier lernst du, was sie ausmacht und warum sie auch Fehler verursachen können.
Deine Lernziele
Hake ab, was du schon kannst. Löst du alle Aufgaben eines Abschnitts, hakt Mela das Ziel für dich ab.
4 Abschnitte
Ein Prozess bezeichnet den Ablauf eines Computerprogramms. Ein Thread ist ein Ausführungsstrang (eine Ausführungsreihenfolge) in der Abarbeitung eines Programms. Er ist Teil eines Prozesses. Man nennt ihn auch Aktivitätsträger oder leichtgewichtiger Prozess. Hier geht es um den Thread im engeren Sinne, den Kernel-Thread. Das Betriebssystem steuert ihn.
Jeder Thread besitzt einen eigenen Threadkontext. Dazu gehören ein unabhängiger Registersatz mit dem Befehlszeiger (Instruction Pointer) und ein eigener Stapel (Stack), meist im gemeinsamen Adressraum des Prozesses. Es kann außerdem Betriebsmittel geben, die nur der Thread benutzen kann oder darf, der sie erzeugt hat. Ein Beispiel ist Thread-local storage.
Die Threads eines Prozesses teilen sich dagegen das Codesegment, das Datensegment und die verwendeten Dateideskriptoren.
Bei den meisten Betriebssystemen hat ein Thread einen Zustand. Aktiv (running) heißt: Der Thread führt Befehle auf der CPU aus. Bereit (ready) heißt: Der Thread ist gestoppt, damit ein anderer Thread rechnen kann. Blockiert (waiting) heißt: Der Thread wartet auf ein Ereignis, meist darauf, dass ein Betriebssystem-Dienst fertig ist. Inaktiv heißt meist: Der Thread wird gerade neu eingerichtet oder hat fertiggerechnet.
Definition
Thread
Ein Thread ist ein Ausführungsstrang in der Abarbeitung eines Programms und Teil eines Prozesses. Er besitzt einen eigenen Threadkontext.
| Eigen pro Thread | Geteilt im Prozess |
|---|---|
| Registersatz mit Befehlszeiger | Codesegment |
| Stapel (Stack), meist im gemeinsamen Adressraum | Datensegment |
| Betriebsmittel nur für den erzeugenden Thread (möglich) | Dateideskriptoren |
Teste dich
Einem Prozess sind ein Adressraum und weitere Betriebssystemmittel zugeordnet. Prozesse sind gegeneinander abgeschirmt: Greift ein Prozess auf Adressen oder Betriebsmittel zu, die ihm nicht zugeteilt wurden, schlägt das fehl. Das Betriebssystem bricht ihn dann ab.
Ein Prozess kann mehrere Threads enthalten, aber auch nur einen einzigen. Die Threads teilen sich innerhalb eines Prozesses die Prozessoren, den Speicher und andere Ressourcen wie Dateien und Netzwerkverbindungen.
Deshalb ist der Verwaltungsaufwand für Threads üblicherweise geringer als für Prozesse. Beim Wechsel zwischen Threads ist kein vollständiger Wechsel des Prozesskontextes nötig, weil alle Threads einen Teil des Prozesskontextes gemeinsam verwenden. Die Umschaltung zwischen Prozessen braucht im Betriebssystem mehr Rechenzeit.
Auch der Austausch von Daten unterscheidet sich. Threads desselben Prozesses verwenden denselben Adressraum, ihre Kommunikation ist von vornherein sehr einfach. Der Informationsaustausch zwischen Prozessen kann dagegen aufwendig sein, zum Beispiel bei message passing.
Bei den meisten bekannten Unix-Systemen (außer Linux) gilt: Ein Programm, das sich falsch verhält, kann seinen eigenen Prozess stören. Das Betriebssystem und andere Prozesse bleiben dabei ungestört.
| Merkmal | Prozess | Threads im Prozess |
|---|---|---|
| Speicher | Adressraum ist dem Prozess zugeordnet | Teilen sich den Speicher des Prozesses |
| Isolation | Gegeneinander abgeschirmt | Teilen sich Speicher, Dateien und Netzwerkverbindungen |
| Aufwand | Umschaltung braucht mehr Rechenzeit | Verwaltungsaufwand üblicherweise geringer |
Beispiel: Ursprüngliches Amiga OS: schnell, aber ungeschützt
- 1Das Betriebssystem unterstützte Threads, aber keine Prozesse.
- 2Es vermied dadurch den Zusatzaufwand des Speicherschutzes und war deshalb effizienter.
- 3Der Preis: Applikationsfehler konnten den gesamten Computer lahmlegen.
Teste dich
In der weiten Begriffsauffassung ist Nebenläufigkeit (mitunter auch Parallelität genannt) die Eigenschaft eines Systems, mehrere Aufgaben, Berechnungen oder Befehle gleichzeitig ausführen zu können. Die Operationen können dabei nur scheinbar gleichzeitig laufen, zum Beispiel im Multitasking auf einem Prozessor. Sie können auch echt nebenläufig laufen, zum Beispiel auf einem Mehrkernprozessor oder auf mehreren Computern, die über ein Netzwerk verbunden sind.
In der engeren Begriffsauffassung unterscheidet man genauer. Die nebenläufige Behandlung (englisch concurrency) ist dann vor allem ein Konzept, reale Vorgänge abzubilden. Sie ist auch dann sinnvoll, wenn nur ein einziger CPU-Kern zur Verfügung steht. Die Parallelverarbeitung (englisch parallelism) meint dagegen echt gleichzeitige Berechnung auf mehreren Kernen, meist für ein einziges Problem.
Für Threads heißt das: Threads innerhalb desselben Prozesses können verschiedenen Prozessoren zugeordnet sein. Dann lassen sich umfangreiche Aufgaben auf mehrere Prozessorkerne verteilen. Ein Programm kann zum Beispiel seine Oberfläche bedienen und gleichzeitig auf eine Eingabe warten.
Nicht alles lässt sich nebenläufig ausführen. Müssen Ablaufschritte in einer festen Reihenfolge nacheinander laufen, kann man sie nicht nebenläufig ausführen.
Definition
Nebenläufigkeit
Nebenläufigkeit ist die Eigenschaft eines Systems, mehrere Aufgaben, Berechnungen oder Befehle gleichzeitig ausführen zu können. Die Ausführung kann nur scheinbar oder echt gleichzeitig sein.
Merke: Nebenläufig heißt nicht automatisch echt gleichzeitig: Auf einem Prozessor können Operationen nur scheinbar gleichzeitig laufen.
Teste dich
Alle Threads nutzen manche Betriebsmittel gemeinsam. Diese gemeinsame Nutzung kann zu Konflikten führen. Solche Konflikte müssen mit Synchronisationsmechanismen aufgelöst werden.
Ein typischer Konflikt ist die Wettlaufsituation (Race Condition). Hier hängt das Ergebnis einer Operation vom zeitlichen Verhalten einzelner Operationen ab. Das Erhöhen eines Werts besteht aus drei Schritten: Der Wert wird aus dem externen Speicher in den internen Speicher gelesen. Dann wird er im internen Speicher um 1 erhöht. Zuletzt wird er in den externen Speicher zurückgeschrieben. Arbeiten zwei Systeme, nennen wir sie A und B, gleichzeitig und ist die Reihenfolge ihrer Befehle unbestimmt, kann ein falsches Ergebnis herauskommen.
Zur Vermeidung muss A den Zugriff auf den Wert bis zum Abschluss der Veränderung sperren. Dann muss B warten. Erst wenn A die Sperrung aufhebt, gelingt sie B. In Java werden kritische Abschnitte mit synchronized realisiert. Auch Semaphore können eingesetzt werden.
Solche Effekte treten sporadisch auf und sind kaum reproduzierbar. Das macht die Fehlersuche schwierig. Ein nebenläufiges Programm kann leicht in einen nicht vorgesehenen Gesamtzustand geraten, der sich zum Beispiel durch Deadlocks, Datenfehler und Abstürze äußert.
Definition
Wettlaufsituation (Race Condition)
Eine Konstellation, in der das Ergebnis einer Operation vom zeitlichen Verhalten einzelner Operationen abhängt.
Beispiel: Zwei Systeme erhöhen den Wert 1
- 1Erwartet wird 3, wenn A und B den Wert 1 je um 1 erhöhen.
- 2Fehlerfall: A und B lesen gleichzeitig beide den Wert 1 ein.
- 3Beide erhöhen intern auf 2, der gespeicherte Wert ist noch 1.
- 4Beide speichern: Es steht 2 statt 3 im Speicher.
- 5Mit Sperre: A sperrt, liest 1, erhöht auf 2, speichert 2, hebt die Sperre auf.
- 6Danach liest B den Wert 2, erhöht auf 3 und speichert 3.
Teste dich
Alles auf einen Blick
Thread
Thread
ein Ausführungsstrang, der Teil eines Prozesses ist
Eigen
Registersatz mit Befehlszeiger und Stapel
Geteilt
Codesegment, Datensegment und Dateideskriptoren
Prozess
gegeneinander abgeschirmt, Umschaltung braucht mehr Rechenzeit
Nebenläufig
nur scheinbar oder echt gleichzeitig
Synchronisation
nötig, weil gemeinsame Daten zu Konflikten führen können
Musteraufgabe · Schritt für Schritt
Zähler erhöhen: ohne und mit Sperre (erfundenes Beispiel)
- 1Annahme: Der gespeicherte Zähler steht auf 5. Die Threads A und B erhöhen ihn je um 1. Erwartet wird 7.
- 2Ohne Sperre, ungünstige Reihenfolge: A liest 5 ein, B liest ebenfalls 5 ein.
- 3A erhöht intern auf 6, B erhöht intern auf 6. Der gespeicherte Wert ist noch 5.
- 4A speichert 6, B speichert 6. Im Speicher steht 6 statt 7.
- 5Mit Sperre: A sperrt, liest 5, erhöht auf 6, speichert 6 und hebt die Sperre auf.
- 6Danach sperrt B, liest 6, erhöht auf 7 und speichert 7. Ergebnis: 7.
Fehler finden
Prüfe die Aussagen zur Nebenläufigkeit In einer Zeile steckt ein Fehler. Tippe sie an.
Fehler in Zeile 4Die Aussage verlangt mehrere Kerne, obwohl das nicht stimmt. Richtig: Nebenläufige Behandlung ist in der engeren Begriffsauffassung auch dann sinnvoll, wenn nur ein einziger CPU-Kern zur Verfügung steht.
Lückentext
Wähl in jeder Lücke das passende Wort und prüf dann deine Antworten.
Ein Thread im Zustand ist gestoppt, um einen anderen Thread rechnen zu lassen. Im Multitasking auf einem Prozessor können Operationen nebenläufig laufen. Erst wenn A die Sperrung , gelingt sie B.
Karteikasten
Erst selbst überlegen, dann umdrehen.
Übung mit Feedback