Vorwort | 6 |
Inhalt | 8 |
1 Einführung | 14 |
2 Basistechniken | 20 |
2.1 Formen der Nebenläufigkeit | 21 |
2.1.1 Hard- und Software – eine Kurzeinführung | 21 |
2.1.1.1 Computer-Hardware | 21 |
2.1.1.2 Computer-Software | 22 |
2.1.2 Nebenläufigkeit in Hardware | 23 |
2.1.3 Nebenläufigkeit in Software | 25 |
2.2 Die Rolle des Betriebssystems | 26 |
2.2.1 Systemarchitekturen | 26 |
2.2.1.1 Aufgaben und Schnittstellen | 26 |
2.2.1.2 Virtualisierung | 29 |
2.2.1.3 Netzdienste und verteilte Systeme | 31 |
2.2.2 Betriebsarten | 33 |
2.2.3 Prozesse und Threads | 35 |
2.2.3.1 Prozesse | 35 |
2.2.3.2 Threads | 37 |
2.2.3.3 Der Lebenszyklus | 38 |
2.2.4 Implementierungsaspekte | 40 |
2.2.4.1 Buchführung | 40 |
2.2.4.3 Scheduling | 41 |
2.3 Prozesse und Threads in UNIX/Linux | 43 |
2.3.1 Kommandos der Benutzerschnittstelle | 43 |
2.3.2 Grundlegende API-Funktionen für Prozesse | 46 |
2.3.2.1 Die Funktion fork() | 47 |
2.3.2.2 Weitere Funktionen | 49 |
2.3.2.3 Programmbeispiele | 51 |
2.3.3 Grundlegende API-Funktionen für Threads | 56 |
2.3.3.1 Pthreads: pthread_create(), pthread_exit() | 56 |
2.3.3.2 Pthreads: pthread_join(), pthread_cancel() | 59 |
2.3.3.3 vfork() und clone() | 60 |
2.4 Threads in Java | 61 |
2.4.1 Die Klasse Thread | 61 |
2.4.1.1 run() und start() | 62 |
2.4.1.2 join() | 64 |
2.4.1.3 Weitere Methoden | 65 |
2.4.2 Grundlegende Programmiertechniken | 65 |
2.4.2.1 Zugriff auf gemeinsame Variablen | 65 |
2.4.2.2 Beenden von Threads | 66 |
2.5 Zusammenfassung und Ausblick | 68 |
2A Basistechniken: Aufgaben | 70 |
2A.1 Wissens- und Verständnisfragen | 70 |
2A.2 Sprachunabhängige Anwendungsaufgaben | 72 |
2A.3 Programmierung unter UNIX/Linux | 74 |
2A.4 Programmierung in Java | 76 |
3 Synchronisation | 80 |
3.1 Synchronisationsbedingungen | 80 |
3.1.1 Elementare Bedingungen | 80 |
3.1.1.1 Wechselseitiger Ausschluss | 81 |
3.1.1.2 Reihenfolgebedingung | 82 |
3.1.2 Komplexere Probleme | 83 |
3.1.2.1 Erzeuger-Verbraucher-Problem | 84 |
3.1.2.2 Leser-Schreiber-Problem | 84 |
3.1.2.3 Philosophenproblem | 85 |
3.2 Einfache Synchronisationsmechanismen | 85 |
3.2.1 Grundlegende Eigenschaften | 86 |
3.2.2 Interruptsperren | 86 |
3.2.3 Spinlocks | 87 |
3.2.4 Signale und Events | 91 |
3.3 Synchronisation durch Semaphore | 92 |
3.3.1 Arbeitsprinzip von Semaphoren | 92 |
3.3.1.1 Datenstrukturen und Operationen | 92 |
3.3.1.2 Semaphoroperationen in Bild und Notation | 94 |
3.3.1.3 Varianten und Erweiterungen | 96 |
3.3.2 Einsatz bei Standardproblemen | 97 |
3.3.2.1 Wechselseitiger Ausschluss | 97 |
3.3.2.2 Reihenfolgebedingung | 98 |
3.3.2.3 Erzeuger-Verbraucher-Problem | 99 |
3.3.2.4 Leser-Schreiber-Problem | 100 |
3.3.2.5 Philosophenproblem | 102 |
3.3.3 Systematische Lösung von Problemen | 103 |
3.3.4 Fehlerquellen | 106 |
3.3.4.1 Deadlocks: Problematik | 107 |
3.3.4.2 Deadlocks: Lösungen | 108 |
3.3.4.3 Missachtung der Atomarität | 109 |
3.3.4.4 Einsatz von sleep() | 110 |
3.3.4.5 Mangelnde Fairness | 110 |
3.4 Synchronisation durch Monitore | 111 |
3.4.1 Grundprinzip von Monitoren | 111 |
3.4.1.1 Definition des Monitorbegriffs | 111 |
3.4.1.2 Beispiel: Einfacher Ringpuffer mit Überschreiben | 112 |
3.4.2 Bedingungsvariablen | 113 |
3.4.2.1 Zweck und Einsatz | 113 |
3.4.2.2 Beispiel: Ringpuffer für Erzeuger/Verbraucher | 115 |
3.4.2.2 Beispiel: Ringpuffer für Erzeuger/Verbraucher | 115 |
3.4.3 Lösung weiterer Standardprobleme | 116 |
3.4.3.1 Reihenfolgebedingung | 116 |
3.4.3.2 Leser-Schreiber-Problem | 117 |
3.4.3.3 Philosophenproblem | 118 |
3.5 Mechanismen in UNIX/Linux | 119 |
3.5.1 Signale | 119 |
3.5.2 Lock-Dateien | 121 |
3.5.3 Semaphore | 122 |
3.5.3.1 Erzeugen von Semaphorgruppen | 122 |
3.5.3.2 Initialisieren und Löschen | 124 |
3.5.3.3 P- und V-Operationen | 126 |
3.5.3.4 Programmstrukturen und -beispiele | 128 |
3.5.4 Mutexe mit Bedingungsvariablen | 133 |
3.5.4.1 Mutexe | 133 |
3.5.4.2 Bedingungsvariablen | 133 |
3.5.4.3 Beispiel: Erzeuger-Verbraucher mit Ringpuffer | 134 |
3.6 Mechanismen in Java | 136 |
3.6.1 Atomare Operationen | 136 |
3.6.1.1 Basistypen | 136 |
3.6.1.2 Collections | 137 |
3.6.2 Semaphore | 137 |
3.6.2.1 Die Klasse Semaphore | 137 |
3.6.2.2 Beispiel: Reihenfolgebeziehung | 138 |
3.6.3 Monitore | 139 |
3.6.3.1 synchronized | 139 |
3.6.3.2 wait() und notify() | 141 |
3.6.3.3 Die Interfaces Lock und Condition | 143 |
3.6.4 Weitere Mechanismen | 144 |
3.7 Zusammenfassung und Ausblick | 145 |
3A Synchronisation: Aufgaben | 148 |
3A.1 Wissens- und Verständnisfragen | 148 |
3A.2 Sprachunabhängige Anwendungsaufgaben | 151 |
3A.3 Programmierung unter UNIX/Linux | 156 |
3A.4 Programmierung in Java | 159 |
4 Kommunikation | 162 |
4.1 Grundlegende Begriffe | 162 |
4.1.1 Arten der Kommunikation | 162 |
4.1.2 Sender-Empfänger-Beziehungen | 164 |
4.1.2.1 Ein oder mehrere Sender und Empfänger | 164 |
4.1.2.2 Direkte vs. indirekte Kommunikation | 165 |
4.1.2.3 Enge vs. lose zeitliche Kopplung | 166 |
4.1.3 Kommunikation in Rechnernetzen | 167 |
4.1.3.1 Schnittstellen: Sockets | 167 |
4.1.3.2 Protokolle und Protokollstacks | 168 |
4.1.3.3 Der Protokollstack des Internets | 170 |
4.2 Techniken in UNIX/Linux | 171 |
4.2.1 Shared Memory | 172 |
4.2.1.1 API-Funktionen | 172 |
4.2.1.2 Programmbeispiel: Erzeuger-Verbraucher-System | 174 |
4.2.2 Pipes | 175 |
4.2.2.1 Benannte Pipes | 176 |
4.2.2.2 Unbenannte Pipes | 177 |
4.2.3 Message Queues | 178 |
4.2.3.1 API-Funktionen: Erzeugen und Löschen | 178 |
4.2.3.2 API-Funktionen: Senden und Empfangen | 179 |
4.2.3.3 Programmbeispiel: Erzeuger-Verbraucher-System | 182 |
4.2.4 Sockets | 183 |
4.2.4.1 Domains und Typen | 183 |
4.2.4.2 API-Funktionen: Übersicht | 184 |
4.2.4.3 API-Funktionen: Erzeugen und Schließen | 186 |
4.2.4.4 API-Funktionen: Verbinden und Kommunizieren | 188 |
4.2.4.5 Programmbeispiel: Stream-Sockets | 189 |
4.2.4.6 Programmbeispiel: Datagram-Sockets | 192 |
4.3 Techniken in Java | 194 |
4.3.1 Übersicht | 194 |
4.3.2 Piped Streams | 195 |
4.3.3 Sockets | 197 |
4.3.3.1 Stream-Sockets | 198 |
4.3.3.2 Datagram-Sockets | 201 |
4.4 Zusammenfassung und Ausblick | 203 |
4A Kommunikation: Aufgaben | 206 |
4A.1 Wissens- und Verständnisfragen | 206 |
4A.2 Sprachunabhängige Anwendungsaufgaben | 209 |
4A.3 Programmierung unter UNIX/Linux | 210 |
4A.4 Programmierung in Java | 214 |
5 Kooperation | 218 |
5.1 Modelle und Techniken | 218 |
5.1.1 Das Client-Server-Modell | 218 |
5.1.1.1 Grundlegende Struktur | 219 |
5.1.1.2 Zeitliche Abläufe | 219 |
5.1.1.3 Implementierungsaspekte | 221 |
5.1.2 Das Peer-to-Peer-Modell | 222 |
5.1.3 Programmiertechniken | 223 |
5.1.3.1 Prozedurorientierte Kooperation | 223 |
5.1.3.2 Objektorientierte Kooperation | 225 |
5.1.3.3 Webbasierte Kooperation | 226 |
5.2 Techniken in UNIX/Linux | 227 |
5.2.1 Kooperation über Sockets | 227 |
5.2.2 Remote Procedure Call (RPC) | 229 |
5.2.2.1 Komponenten und ihr Zusammenspiel | 229 |
5.2.2.2 Schritte der Programmierung | 231 |
5.3 Techniken in Java | 235 |
5.3.1 Remote Method Invocation (RMI) | 235 |
5.3.1.1 Komponenten und ihr Zusammenspiel | 235 |
5.3.1.2 Schritte der Programmierung | 236 |
5.3.2 Dynamische Webseiten | 239 |
5.3.2.1 Applets | 239 |
5.3.2.2 Servlets und Java Server Pages | 241 |
5.3.3 Web Services | 242 |
5.4 Zusammenfassung | 244 |
5A Kooperation: Aufgaben | 246 |
5A.1 Wissens- und Verständnisfragen | 246 |
5A.2 Sprachunabhängige Anwendungsaufgaben | 248 |
5A.3 Programmierung unter UNIX/Linux | 250 |
5A.4 Programmierung in Java | 251 |
Literatur und Internet | 254 |
Internet-Quellen | 255 |
Index | 256 |