Echtzeit- & Betriebssysteme · SoSe 2026 · Otto
08
08_shared_memory_grpc · Vorlesung + Praktikum

Shared Memory & gRPC

Diese Lernseite bündelt Vorlesung 08 und ihr Praktikum. Der Weg führt von Prozessen & Threads über das Syscall-Tracing bis zum eigentlichen Thema – Shared Memory, Semaphoren und gRPC. Jede der drei Praktikums-Aufgaben ist unten animiert erklärt, der komplette Lösungscode aufklappbar.

{{ c.tag }}
{{ c.title }}
{{ c.desc }}
// Aufgabe 1

Prozesse vs. Threads

Beide teilen dieselbe Aufgabe auf mehrere Ausführungseinheiten auf – der entscheidende Unterschied liegt im Adressraum. Threads teilen sich den Speicher, Prozesse sind voneinander isoliert. Das erklärt fast alle Unterschiede in Geschwindigkeit, Overhead und Fehlertoleranz.

Threads

Laufen innerhalb eines Prozesses und teilen sich denselben Adressraum: Heap, globale Variablen, offene Dateien. Kommunikation = direkter Speicherzugriff (sehr schnell), erfordert aber Synchronisation.

Erstellungs-Overhead: gering
Prozesse

Haben einen eigenen, isolierten Adressraum. Der Kernel verwaltet jeden getrennt. Kommunikation braucht explizite IPC-Mechanismen (Dateien, Pipes, Shared Memory …). fork() kopiert den Kontext (Copy-on-Write).

Erstellungs-Overhead: höher
Adressraum-Modell
Wer sieht welchen Speicher?
Prozess (ein Adressraum)
Geteilter Heap
A
B
C (Ergebnis)
A und B werden einmal geladen. Alle Threads greifen direkt darauf zu.
{{ t.label }} → C[{{ t.range }}]

Jeder Thread schreibt in andere Zeilen von C → keine zwei Threads berühren dieselbe Stelle → keine Synchronisation nötig.

{{ pr.label }}
A
B
liest A+B selbst → schreibt Teil-Datei

Jeder Kindprozess öffnet und liest A und B selbst von der Festplatte und schreibt sein Teilergebnis in eine temporäre Datei. Der Elternprozess wartet (waitpid) und fügt die Teile zusammen. Isoliert, aber mit mehr I/O-Aufwand.

Zeilenaufteilung von C
12 Zeilen auf N Einheiten – der Letzte übernimmt den Rest
Zeile {{ row.idx }}
{{ row.tag }}
rowsPerWorker = 12 / {{ workers }} = {{ rowsPerWorker }}
{{ splitNote }}
Speedup & Amdahlsches Gesetz
Der sequentielle Anteil begrenzt den Speedup – egal wie viele Einheiten.
Einheiten N Speedup S(N) max ≈ {{ sMaxLabel }}× ideal S = N
S(N) = 1 / ((1−p) + p/N)
{{ s8Label }}×
bei N = 8
{{ sMaxLabel }}×
Maximum (N→∞)
Lösungscode
{{ c.lineHint }}
{{ ln.num }} {{ ln.mark }} {{ ln.rich }}
{{ ln.ex }}
{{ pt }}
// Aufgabe 2

Syscall-Tracing: libc & Kernel

Jeder printf-Aufruf passiert auf zwei Ebenen: der bequemen libc-Funktion und dem darunterliegenden Kernel-Syscall. ltrace zeigt Ebene 1, strace zeigt Ebene 2.

ltrace

Beobachtet libc-Funktionen. Setzt Breakpoints in die PLT des dynamisch gelinkten Binaries.

strace

Beobachtet Kernel-Syscalls mittels ptrace(2) – hält bei jedem Syscall-Ein/-Austritt an.

Warum 5× printf oft nur 1× write() ergibt
glibc puffert die Ausgabe – Schritt für Schritt
Programmzeile
{{ bufCode }}
{{ bufAct }}
stdout-Puffer (glibc)
{{ l }}
(leer)
ausgelöste Syscalls
{{ s }}
– noch keiner –
malloc → brk / mmap
Kleine und große Allokationen nehmen verschiedene Wege.
{{ allocSyscall }}

{{ allocExplain }}

Adressraum eines Prozesses
hohe Adressen oben, niedrige unten
{{ m.name }} {{ m.desc }}
Lösungscode
{{ c.lineHint }}
{{ ln.num }} {{ ln.mark }} {{ ln.rich }}
{{ ln.ex }}
{{ pt }}
// Aufgabe 3

IPC: Shared Memory & gRPC

Zwei Extrempole der Interprozesskommunikation: Shared Memory ist der schnellste Mechanismus (0 Kopien, kein Kernel dazwischen), gRPC ist die abstrakteste Variante (typsicher, netzwerkfähig, aber mit Overhead durch viele Schichten).

Rückblick: Stack vs. Heap
Woher der Speicher kommt — die Grundlage, um Shared Memory einzuordnen.
EigenschaftStackHeap
{{ sh.k }} {{ sh.stack }} {{ sh.heap }}
Shared Memory: ein Speicher, zwei Adressräume
Beide Prozesse mappen dieselben physischen Seiten (/dev/shm).
Prozess A · virt. 0x7f3c2a015000
{{ shmValA }}
Physische Seiten · /dev/shm
{{ shmValPhys }}
Prozess B · virt. 0x7e91b8c40000
{{ shmValB }}

{{ shmNote }}

Drei Arten der Synchronisation
Shared Memory löst das Wo, Semaphoren und Mutex das Wann. Merkbilder aus der Vorlesung:
{{ st.name }}
Merkbild: {{ st.analogy }} · {{ st.val }}
{{ st.desc }}
Counting Semaphore live · Leihfahrrad-Stand
{{ b.glyph }}
Zähler = {{ bikes }} / 10
{{ bikeNote }}
Producer / Consumer mit Semaphoren
sem_empty (freier Slot) und sem_full (Daten da) steuern das Ping-Pong.
Producer {{ prodState }}
schreibt Batches in den Slot
Slot
{{ slotContent }}
Consumer {{ consState }}
liest Batches, rechnet Summe
sem_empty = {{ semEmpty }}
sem_full = {{ semFull }}
{{ semNote }}
Warum gRPC? Das Problem mit klassischem REST
In verteilten Systemen (Microservices, IoT/Embedded) zählt die Effizienz der IPC.
{{ rp.n }} {{ rp.title }}
{{ rp.desc }}
gRPC ist Googles Open-Source-RPC-Framework: Ein Client ruft eine Methode auf dem Server auf, als wäre sie lokal. Sprachunabhängig (C++ ↔ Java ↔ Python), mit strikter Schnittstellendefinition (IDL) und automatischer Code-Generierung durch protoc.
Der Weg eines gRPC-Aufrufs
stub->Multiply() sieht lokal aus – durchläuft aber viele Schichten.
{{ lay.num }} {{ lay.label }}
{{ grpcNote }}
Die vier Kommunikationsmuster
gRPC kann mehr als Request-Response. Wähle ein Muster:
Client
{{ ar.label }}
Server
{{ patternName }} · {{ patternSub }}
{{ patternDesc }}
Architekturvergleich: gRPC vs. REST
KriteriumgRPCREST
{{ gr.k }} {{ gr.grpc }} {{ gr.rest }}
gRPC einsetzen bei…
{{ u }}
Eher REST/JSON bei…
{{ no }}
IPC-Mechanismen im Vergleich
Von langsam/isoliert bis schnell bzw. netzwerkfähig — Shared Memory und gRPC sind die Extrempole.
MechanismusKopienNetzLatenzAnwendungsfall
{{ r.name }} {{ r.dir }} {{ r.copies }} {{ r.net }} {{ r.latency }} {{ r.use }}
Lösungscode
{{ c.lineHint }}
{{ ln.num }} {{ ln.mark }} {{ ln.rich }}
{{ ln.ex }}
{{ pt }}
// Nachschlagen

Fachwort-Glossar

Die wichtigsten Begriffe – englischer Fachbegriff, deutsche Übersetzung und eine kurze Erklärung.

{{ g.en }} ≈ {{ g.de }}
{{ g.def }}
Kein Begriff gefunden für „{{ glossQuery }}".
// Wissenscheck

Quiz

Aus den Lernzielkontrollen aller drei Blätter. Wähle je eine Antwort und werte am Ende aus.

{{ q.num }} {{ q.text }}
{{ q.explain }}
{{ scoreText }}