# Threads
- **Kleinste ausführbare Einheit** innerhalb eines Prozesses
- ermöglichen **flexiblere**, **reaktionsschnellere** und **effizientere** Programmierung

- müssen sorgfältig überwacht werden, um Probleme zu vermeiden
  - bspw. [Deadlocks](07_Prozesssynchronisation.md#deadlock) oder Rennbedingungen

## Threads vs Prozesse
| **Merkmal**                                     | **Thread**                                                                                          | **Prozess**                                                                                          |
|-------------------------------------------------|-----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| Definition                                      | Kleinste ausführbare Einheit innerhalb eines Prozesses                                              | Unabhängiges Programm in Ausführung                                                                  |
| Ressourcenzuweisung                             | Teilen denselben Adressraum & Ressourcen innerhalb eines Prozesses                                  | Haben eigenen Adressraum und separate Ressourcen                                                     |
| Kommunikation                                   | direkter Zugriff auf gemeinsame Daten<br/>erfordert synchronisierte Mechanismen                     | erfordert aufwändige Mechanismen wie [IPC](09_Interprozesskommunikation.md)                          |
| [Synchronisation](07_Prozesssynchronisation.md) | benötigt Synchronisationsmechanismen um Rennbedingungen zu vermeiden                                | Isoliert voneinander, weniger Rennbedingungen,<br/>aber schwerere Synchronisation zwischen Prozessen |
| Overhead                                        | **geringerer Overhead**                                                                             | höherer Overhead, da separate Adressräume und Ressourcen                                             |
| Ressourcennutzung                               | **effiziente Nutzung innerhalb desselben Prozesses**                                                | höherer Ressourcenverbrauch aufgrund separater Adressräume                                           |
| Erstellung und Terminierung                     | **schnellere Erstellung und Terminierung**<br/>Terminierung beeinflusst nur den spezifischen Thread | Langsamere Erstellung und Terminierung<br/>Beenden eines Prozesses beendet alle seine Threads        |
| Fehlerisolierung                                | Scheitern eines Threads kann gesamten Prozess beeinträchtigen                                       | **Isoliert**, Scheitern beeinflusst keine anderen Prozesse                                           |

- Thread wird auch als _Aktivitätsträger_ oder _leichtgewichtiger Prozess_ benannt
  - ist immer Teil eines Prozesses
    - Prozess kan viele Threads gleichzeitig enthalten
      - werden unabhängig voneinander (_ähnlich Prozesse_) abgearbeitet
    - Prozess besteht bei Erzeugung aus einem Thread
      - wird impliziert mit dem Prozess erzeugt

| **Thread**                              | **Prozess**                         |
|-----------------------------------------|-------------------------------------|
| Leichter Prozess                        | Programm in Ausführung              |
| Gehört zu Prozess                       | Vollständig isoliert                |
| gemeinsamer Speicher                    | eigener Speicher                    |
| geringer Ressourcenverbrauch            | hoher Ressourcenverbrauch           |
| niedriger Zeitbedarf bei Kontextwechsel | hoher Zeitbedarf bei Kontextwechsel |

> Abarbeitung von Threads ist ca. 10-100 mal schneller im Vergleich zur Verarbeitung
> von Prozessen.
> 
> Threads nutzen den gleichen Adressraum, was die Kommunikation erleichtert


## Erzeugung von neuen Threads
- Sehr einfach
  - Code eines Threads ist eine **normal definierte Funktion**, die wieder andere Funktionen aufrufen kann
  - werden von Systemaufrufen gestartet
    - Systemaufruf bekommt die Threadfunktion als Parameter übergeben

## Threads implementieren
- Threads sind i.d.R. im Kern implementiert, ähnlich wie Prozesse
- Threads haben dieselben Zustände wie Prozesse, Bedeutung der Zustände ist identisch
- Kann in vielen Programmiersprachen und Systemen realisiert werden
  - bspw. _C, C++, C#, Java, Python, Swift, ..._

### Befehle mit [POSIX API](06_prozessstruktur.md#posix-api)
- **pthread_create** - Erzeugen eines Threads
- **pthread_exit** - Beenden eines Threads
- **pthread_join** - Warten auf Ende eines Threads
- **pthread_yield** - Aufgaben der CPU

## Fork-Join-Modell
- Paradigma für die parallele Programmierung 
  - Erstellen von Threads (**fork**) und Zusammenführen von Threads (**join**)
- wird gerne in rekursiven Algorithmen verwendet
  - große Aufgabe kann in kleinere Teilaufgaben zerlegt werden
- Jeder Thread kann sich auf eine Teilaufgabe konzentrieren
  - Ergebnisse werden die Ergebnisse kombiniert

![image_157.png](image_157.png)

## FORK
> Durch den Aufruf der Funktion **fork()** in einem Programm werden Threads ebenso wie der
> gesamte Adressraum des Prozesses kopiert
> 
> Es entsteht eine exakte Kopie des aufrufenden Prozesses, einschließlich aller Threads und deren Zustände