# Prozesssynchronisation

## Warum überhaupt Synchronisation?
- mehrere Prozesse arbeiten in einem System koordiniert und in einer bestimmten Reihenfolge/zeitlichen Abfolge
- Multitasking- /Multiprozessor-System
  - mehrere Prozesse gleichzeitig / parallel
    - Prozesse interagieren miteinander
    - Zugriff auf gemeinsame Ressourcen

- Warten auf Operationen (_Wait and Signal_)
- Kritischer Abschnitt (_Critical Section_)
- Rennbedingungen (_Race Conditions_)
- Mutex (_Mutex Lock_)
- Semaphore
- Deadlocks und Ressourcenkonflikte
- Interprozesskommunikation (_IPC_)

## Signale
- dienen als Mechanismus für die Kommunikation 
  - zwischen Prozessen
  - zwischen Betriebssystem und Prozessen
- Signal ist eine Benachrichtigung and ein Prozess, dass Ereignis aufgetreten ist

### Zweck
- Behandlung von Ausnahmen
- Kommunikation von Ereignissen
- Steuerung von Prozessen

- Ermöglicht 
  - Implementierung von asynchronen Benachrichtigungen
  - Behandlung von außergewöhnlichen Ereignissen

### Beispiel
Terminalbefehl **- man signal**
![image_83.png](image_83.png)

### Signalhandler
- Funktion/Codeabschnitt, welcher _onSignal_ ausgeführt wird

#### Was passiert beim Aufruf eines Signalhandlers
- Prozess wird bei Eintreffen eines Signals angehalten
- Prozesszustand wird gesichert
- Signalhandler wird aufgerufen
  - darf beliebige Systemaufrufe veranlassen (_sollte sie aber nicht_)
- Bei Beendigung des Signalhandlers
  - Prozess läuft weiter wo er unterbrochen wurde

## Warten
### Aktives Warten (Polling)
- Prozess prüft ob Bedingung erfüllt ist
  - _bspw. in Schleifenstrukturen_
```c++
while (!Bedingung){
  //aktives Warten
}
```

### Passives Warten
- Prozess wird in Wartezustand versetzt
  - wird reaktiviert, wenn Bedingung erfüllt wurde
  - währenddessen können andere Prozesse auf der CPU laufen

```c++
wait_for_condition(); //Prozess geht in Wartezustand

//Irgendwann Reaktivierung
resume_execution();
```

## Sperren
- Koordiniert Zugriff auf gemeinsame Ressourcen durch mehrere Prozesse oder Threads
  - Nur ein Prozess/Thread gleichzeitig 
    - Dateninkonsistenzen oder Rennbedingungen werden vermieden

## Mutex (Mutual Exclusion)
- Sperre, welche exklusiven Zugriff auf Ressource steuert
  - Prozess sperrt/entsperrt vor/nach Zugriff auf Ressource

### Nutzung
- Dateizugriffe
- Netzwerkkommunikation
- Zugriff auf gemeinsam genutzte Datenstrukturen
- Hardware

## Semaphores
- Ähnlich wie Mutex, nur zusätzlich mit Kommunikation durch [Signale](#signale)

## Mutex vs Semaphore
Befehle mit [POSIX API](06_prozessstruktur.md#posix-api)
### Mutex
- **pthread_mutex_t** _Datentyp für Mutex_
- **pthread_mutex_init** _Erzeugen eines Mutexobjekts_
- **pthread_mutex_unlock** _Entsperren_
- **pthread_mutex_lock** _Sperren_
- **pthread_mutex_trylock** _Versuchendes Sperren_
- **pthread_mutex_destroy** _Löschen des Mutexobjekts_

### Semaphore
- **sem_t** _Datentyp für Semaphor_
- **sem_init** _Initialisieren eines Semaphors (notwendig)_
- **sem_post** _up Operation: Semaphor um 1 erhöhen_
- **sem_wait** _down Operation: Semaphor um 1 vermindern oder blockieren_
- **sem_trywait** _wie sem_wait, aber Aufruf kehrt zurück, falls sem_wait blockieren würde_
- **sem_timedwait** _wie sem_wait, aber mit time-out, falls blockiert_
- **sem_getvalue** _Wert des Semaphors auslesen_
- **sem_destroy** _Löschen eines Semaphors_

### Was nimmt man jetzt?
> Hängt von Anforderungen und Charakteristiken des spezifischen Anwendungsfalls ab
> 
> Es ist wichtig, Synchronisationsmechanismen sorgfältig zu verwenden,
> um sicherzustellen, dass kritische Abschnitte effizient und sicher koordiniert werden

- **Praktisches Anwendungsbeispiel: Siehe Praktikum 4**
  - Postverteilungszentrum bestückt Verteiler der Post
    - Konfliktsituationen:
      - wer wird jetzt grad bestückt?
      - wie viele kann man gleichzeitig bedienen?
      - Wann ist ein Verteiler voll?
      - Welcher Postbote darf zuerst an den Briefkasten dran?
        - Mutex - Briefkasten freigegeben / gesperrt
      - Muss geklingelt werden (bspw. Einschreiben)
        - Semaphore - weil es muss benachrichtigt werden

## Deadlock
(Stillstand / Blockade) ist eine Situation, bei der zwei oder mehr Prozesse auf unbestimmte Weise blockiert sind, weil sie auf die Freigabe von Ressourcen warten

### Entstehungsbedingungen von Deadlocks
- **Gegenseitiger Ausschluss**
  - Mindestens eine Ressource muss exklusiv für immer nur einen Prozess sein
- **Warte-Zustand**
  - Prozess hält eine Ressource und wartet bis er die nächste kriegt
- **Nicht-Preemption**
  - Ressourcen können nicht zwangsweise (_sondern nur freiwillig_) von Prozess/Thread entzogen werden
- **Zyklus in den Wartebeziehungen**
  - Kette von Prozessen/Threads
  - P1 wartet auf Ressource von P2, P2 auf P3, ..., PN auf P1

### Erkennung von Deadlocks
_Betriebsmittelgraf_ (Ressource Allocation Graph)
- Modelliert _Zuteilung und Freigabe_ von Ressourcen zwischen Prozessen

![image_84.png](image_84.png)

- Falls es mehrere Instanzen einer Ressource gibt
  - **matrizen-basiertes Verfahren**
    - Ressourcenvektor
    - Belegungsmatrix
    - Anforderungsmatrix
    - Ressourcenrestvektor

#### Beispiel Erkennung von Deadlocks
![image_85.png](image_85.png)
![image_86.png](image_86.png)

### Livelock
- Form der Blockierung von 2 oder mehr Prozessen, welche aber ständig zwischen mehreren Zuständen wechseln und ihnen nicht entkommen können
- Bspw.:
  - 2 Personen kommen sich auf dem Gang entgegen und weichen die ganze Zeit in die gleiche Richtung aus
    - Deadlock:
      - Personen stehen gegenüber und warten bis der andere beiseite geht, was nicht passiert