Betriebssysteme // Kapitel 6: IPC (Shared Memory & MQs)
Aus welchen 3 Speicherbereichen besteht ein Prozess (Stack, Heap, ...)?
1. Stack (LIFO, automatisch, lokale Variablen)
2. Heap (manuell mit `malloc()`/`free()`, langlebige Objekte)
3. Static/Constant (globale/statische Variablen).
2. Heap (manuell mit `malloc()`/`free()`, langlebige Objekte)
3. Static/Constant (globale/statische Variablen).
Was ist 'Shared-Memory'?
Ein explizit angelegter Speicherbereich, auf den mehrere Prozesse zugreifen können (lesen und schreiben).
Wie erstellt man ein Shared-Memory-Segment in C (Linux)?
`shm_open()`: Erstellt/öffnet ein Segment (Pseudo-Datei unter `/dev/shm`) und gibt einen File-Descriptor zurück. Neue Segmente haben Größe 0.
Wie ändert man die Größe eines neuen Shared-Memory-Segments?
Mit `ftruncate()`.
Was macht `mmap()` im Kontext von Shared-Memory?
Blendet das Shared-Memory-Segment (via File-Descriptor) direkt in den Adressraum des Prozesses ein. Dies ist effizienter als `read()`/`write()`.
Was ist das Hauptproblem bei Shared-Memory?
Race Conditions. Wenn mehrere Prozesse gleichzeitig auf dieselben Daten zugreifen, kann dies zu Inkonsistenzen führen. (Synchronisation ist nötig!)
Was ist das Prinzip von Message-Queues (MQ)?
Asynchrone Kommunikation. Sender sendet Nachricht (ohne auf Empfänger zu warten). Empfänger holt Nachricht ab, wenn er bereit ist. Die Queue speichert die Nachrichten zwischen.
Was sind Vorteile von POSIX Message-Queues gegenüber Shared-Memory?
Keine Race-Conditions beim Senden/Empfangen (implizit synchronisiert). Nachrichten können Prioritäten haben.
Was sind die Hauptfunktionen für POSIX Message-Queues in C?
`mq_open()` (erstellen/öffnen)
`mq_unlink()` (löschen)
`mq_send()` (senden, blockiert wenn voll)
`mq_receive()` (empfangen, blockiert wenn leer).
`mq_unlink()` (löschen)
`mq_send()` (senden, blockiert wenn voll)
`mq_receive()` (empfangen, blockiert wenn leer).
Was sind Unix Domain Sockets (AF_UNIX)?
Lokale Sockets, die IPC auf demselben Rechner ermöglichen. Nutzen das Socket-API (wie TCP/IP), sind aber effizienter, da sie nicht über den Netzwerk-Stack gehen.
Beschreibe das Client/Server-Prinzip bei Sockets.
Server: `socket()` -> `bind()` -> `listen()` -> `accept()`
Client: `socket()` -> `connect()`
Beide: `send()`/`recv()`
Client: `socket()` -> `connect()`
Beide: `send()`/`recv()`