Skript zur Vorlesung Betriebssysteme
Speicher- verwaltung
CPU Prozesse
Platte Netzwerke
Vorlesung Betriebssysteme Prof. Dr. Jobst
Gliederung
1. Einführung 2. Prozesse
3. Prozesskommunikation, Synchronisierung 4. Deadlocks – Systemverklemmung
5. Ein Modell - Betriebssystem: Mini-Org 6. Speicherverwaltung
7. Peripherie, Sicherheit
Stand:
Geschrieben von Herrn Dipl. Inf. (FH) Eyke Langhans nach der Vorlesung Betriebssysteme/Jo im WS1997/1998
Überarbeitet von Prof. Dr. F. Jobst, SS1998 bis einschl. SS 2001
Literatur
1. Bach, M.J.: UNIX: Wie funktioniert das Betriebssystem?, Hanser 1991 2. Ben-Ari, M.: Principles of concurrent Programming, PHI 1982
3. Bic/Shaw : Betriebssysteme, Hanser 1990
4. Intel: Pentium Processor User´s Manual, Vol. 3, Architecture and Programming, 1993 5. Hart, J.M.: Win32 System Programming, Addison Wesley, 1997
6. Kruglinski,/Sheperd/Wingo: Inside Visual C++ 6.0, Microsoft Press 1998
7. Microsoft: Windows NT Workstation: Die technische Referenz, Microsoft Press 1997 8. Microware: OS-9/68000: Operating System Technical Manual
9. MSDN, Microsoft Developer Network
10. Richter, J.: Windows Programmierung für Experten, Microsoft Press 1995 11. Rochkind, M.J.: Advanced UNIX-Programming, PHI 1985
12. Silverschatz/Galvin : Operating System Concepts, 5thEd. 1998, Addison Wesley 13. Solomon, David: Inside Microsoft Windows NT, 2. Auflage, Microsoft Press 1998 14. Stallings, W.: Operating Systems, PHI, 3rd Ed. 1998
15. Stevens, W.R.: Advanced Programming in the UNIX Environment, Addison Wesley 1992
16. Tanenbaum, A.S.: Betriebssysteme Teil 1, Hanser 1990 17. Tanenbaum, A.S.: Moderne Betriebssysteme, Hanser 1994
1. Einleitung
1.1. Was ist ein Betriebssystem?
DIN 44300:Die Programme eines digitalen Rechensystems, die zusammen mit den Eigenschaften der Rechneranlage die Basis der möglichen Betriebsarten der digitalen Rechensysteme bilden und insbesondere die Abwicklung steuern und überwachen.
• Aufgaben:Anwenderschnittstelle: Zugriff auf Hardware
• API (Application Programmers Interface): Betriebssystem liefert den Zugriff Sichten auf das Betriebssystem
Erweiterte Maschine
z.B. Floppy-Zugriff: Controller mit hat 16 Befehle mit jeweils 1 bis 9 Bytes im Geräteregister. Diese dienen dem Lesen und Schreiben von Daten, der Bewegung des Plattenarms, der Formatierung der Spuren, der Initialisierung, der Abfrage, dem Zurücksetzen und der Neukalibrierung des Controllers und der Geräte. Die grundlegenden Befehle READ und WRITE benötigen jeweils 13 Parameter, die in 9 Bytes gepackt sind. Zurückgegeben werden 23 Felder in 7 Byte. Problem: Ein-/Ausschalten des Motors; auf keinen Fall zu lange laufen lassen [16, 17]. Das Betriebssystem versteckt also die komplexe Hardwarestruktur, bietet also eine erweiterte Maschine, die leichter zu programmieren ist. Das Betriebssystem bietet: Sektorzugriff / Dateikonzept.
Anwender High-Level Low-Level Hardware
Anwender MS-DOS BIOS
Hardware
Betriebsmittelverwaltung [16, 17]:Betriebsmittel: Speicher Sekundärspeicher, CPU´s, Netzwerk, Maus, Bildschirm, Terminals usw.Die Aufgabe des Betriebssystems ist die geordnete und kontrollierte Zuteilung der Betriebsmittel bei gleichzeitigen Zugriff von mehreren Programmen.
Speicherhierarchie
CD-ROM, Band Festplatte
RAM Cache
Anforderungsprofile
Rechnerart Betriebssystem Großrechner: Interaktiv,
Stapelverarbeitung
MVS
Workstation: UNIX, NT
PC´s: Windows, Mac
Prozessrechner: OS/9 Betriebssystem – Baukasten
iRMX, Intel 86er
1.2. Geschichte der Betriebssysteme
a) 0te Generation 1945 - 1955:- Elektronenröhren <= 20.000- Programmierung:
Zusammenstecken von Schalttafeln- Magnetische Trommelspeicher
IBM 1401 IBM 1401 IBM 1401
Zentralrechner IBM 7094 ($25 Mio.)
Drucker
Band Band
Aufruf Compiler Jobkarte für
Abrechnung
LOAD oder
RUN STOP
EOF Fortran
Programm
Daten
b) 1te Generation 1955 - 1960:- FORTRAN 1955 Peter Naur (BNF)- Trennung zwischen Entwickler, Fertigung, Operating, Programmierung, Benutzer ⇒ Beginn der
kommerziellen DV- Typisches Betriebssystem: FMS (FORTRAN Monitoring System) Job:- Aufgabe des Betriebssystem:
→ Daten von Band lesen
→ Programme (z.B. Compiler) von Systemband lesen → Ausgabe auf Band
- Problem: Schlechte CPU - Nutzung
c) 2te Generation 1960 - 1975:
- Geschwindigkeit bei hohen Kosten um Faktor 10 gesteigert.
⇒ Hardware muss besser genutzt werden
→ Multiprogramming
→ Festplatten mit autonomen Controllern (E/A - Kanäle)
→ Virtuelle Speichertechnik
→ Timesharing für Terminals
→ Umfangreiche JCC (Job Control Language)
- Mit dem MULTICS (MULTiplexed Information and Computing System) wollte General Electric ganz Bosten mit Rechnerleistung versorgen. Das Projekt scheiterte zwar, jedoch brachte die Entwicklung viele neue Aspekte und Erfahrungen, u.a. Abgrenzung der einzelnen Tasks, Schutzkonzepte (in 286, 386, 486 und Pentium), virtuelle Speichertechnik.
- ca. 1970: UNIX (Uniplex Information and Computing Service). Entwicklung mit C
d) 3te Generation 1975 bis heute:- Mikroprozessor- Mooresches Gesetz: Alle 18 Monate Verdopplung der Schaltkreise pro Fläche- hohe Rechnerleistung an jedem Ort verfügbar- Internet, Netzwerke- Sichere Betriebssysteme, Fehlertoleranz
Geschichte (tabellarisch)
-> 1955 -> 1960 -> 1965 -> 1975 -> ab 1975
HW Elektronenröhren Transistor IC´s VLSI ab ´78 : 8086 , 68000
SW FORTRAN
LISP COBOL
Algol 60 Algol 68
1970 : Pascal C
Datenbanken Benutzerober- flächen
BS JCL , FMS komplexe JCL OS /360
Multi- programming BS1000 , BS2000 UNIX
DOS , OS/2, Windows, Linux Fehlertolerante BSe
Network – BSe
1.3. Betriebsarten eines Betriebssystem
• Einprogrammbetrieb: wenig Overhead, MS-DOS
• Batchbetrieb: Es laufen verschiedene - nicht interaktive Anwendungen. Das Betriebssystem muss Durchsatz optimieren
• Timesharing - Betrieb: Jeder Anwender hat den Rechner scheinbar für sich. Das Betriebssystem muss Antwortzeiten und Durchsatz optimieren.
• Real - Zeit - Betrieb: Das System muss innerhalb einer definierten Zeit Antworten liefern, damit bestimmte Programme zum Ablauf kommen. Auslastung der Komponenten ist nicht das Ziel. (Relativ selten erforderlich).
2. Prozesse
2.1. Was ist ein Prozess?
Programm Prozess
• statisch, wiederholbar • dynamisch, nicht wiederholbar
• einmalige Abläufe (Prozessidentifikation PID)
• braucht ein Programm
• ein Objekt i. S. der Informatik
(Prozessbeschreibung und Methoden) Im Sinne eines Betriebssystem besteht ein Prozess aus:
• unveränderlicher Teil: Code, Konstanten
• veränderlicher Teil: Globale Daten, Stack, Heap
• Kontext (Umgebung): Register, Zeit, Verwaltungsdaten
Eigenschaften: Auf einem n- Prozessorsystem läuft zu einem Zeitpunkt maximal n Prozesse.
Das Betriebssystem ordnet einzelnen Prozessen das Betriebsmittel CPU zu und entzieht es ihnen wieder.
Prozeß (Netscape)
JAVA Threads GUI Threads READ am Socket
Beispiel:
Threads: leichtgewichtiger Prozess mit minimalen Satz an Verwaltungsdaten.
Ein Prozess kann aus verschiedenen Threads bestehen:
Alle Threads eines Prozesses benutzen dabei den gleichen Adressraum.
Beispiel: Solaris [14]
Prozess: Ein unter UNIX üblicher Prozess mit Adressraum, Stack und TCB
User-Level-Thread (ULT[14]): Auf Anwenderebene mit Hilfe einer Solaris-Standard- Bibliothek implementiert. Die ULT´s sorgen für Parallelität auf der Anwendungsebene. Bei verschiedenen Fenstern ist nur eines aktiv. Man hat also Parallelität auf der Anwendungsebene, braucht aber keine Parallelität auf der Kernel-Ebene.
Kernel Thread: Fundamentale Einheit für die Ablaufsteuerung für CPU-Zuteilung
Leichtgewichtiger Prozess (LWP): Zuordnung zwischen ULT und Kernel-Thread. Jeder LWP kann als Zuordnung zwischen einem ULT und einem Kernel-Thread betrachtet werden.
Beispiel: Microsoft Windows NT [9, 13]
Windows NT kennt Prozesse sowie Threads. Jedem Prozess ist mindestens ein Thread zu- geordnet. Ab Version 4.0 kennt NT den Begriff „Fiber“. Ein Fiber ist programmtechnisch eine Prozedur. Ein Thread kann mit dem Aufruf ConvertThreadToFiber in einen Fiber um- gewandelt werden. Danach kann dieser Fiber via kooperativem Multitasking mit anderen Fibers zusammenarbeiten. Entscheidend ist, dass der Fiber explizit Aufrufe wie SwitchToFiber
benutzen muss, um auf andere Fibers umzuschalten.
2.2. Konkrete Darstellung von Prozessen
Jeder Prozess hat einen TCB (Task Control Block), auch PLB (Prozess Leit Block) genannt.
Pro Prozess gibt es genau einen PLB. Alle PLB´s werden z.B. in einem Array verwaltet.
PLB:
Prozessverwaltung A Speicherverwaltung B Dateiverwaltung C
• Register • Programm • Root Directory
• Prozesszustand • Daten • Aktuelle Directories
• CPU - Zeit • Shared Memory • Zugriffsrechte
• PID bzw. TID
Die PLB´s müssen bei Prozesswechsel (Kontext - Umschaltung) „ausgewechselt“ werden:
Laufende
Prozesse, so viele,
Andere Prozesse Betriebssystem
Kontext-Umschaltung
Die Felder A, B, C müssen bei einem Kontextwechsel bearbeitet werden.
⇒ Prozessumschaltung sehr aufwendig.
Abhilfe: Leichtgewichtige Prozesse „Threads“
Realisierung von Threads
Ein Prozess enthält anfangs genau einen Thread (Threads sind unter UNIX plattformabhängig)
fork Thread 2
Thread 1
Daten 2 Daten 1
Daten gleich!
Prozesse Threads
Der Prozess kann (je nach Betriebssystem) zusätzliche Threads starten. Dabei wird nur Feld A neu angelegt. Die Threads benutzen die Felder B und C gemeinsam.
⇒ Frage der Thread – Sicherheit Der PLB (TCB)
a) Programmcode: u. U. von mehreren Programmen gleichzeitig benutzen. - Nur bei nicht codemodifizierenden Programmen.
b) Programmdaten: - Konstanten mit Werten vorbelegen -
c) Betriebssystem muss Adreßkonstanten einsetzen -
d) DLL´s werden von Win95/NT über neue Prozesse informiert
e) Registersatz, Stack: z.B. Intel Architektur - 16 BitAlternativen: Großrechner (siehe IBM 370) mit Spezialbefehlen zum sichern und wiederherstellen von Registern + mehrere
Registersätze. Oder: Motorola 68000 (1978)
Segment-Register :
AX CS IP Flags
nach Interrupt Standard Borland und
Microsoft Format
SS:SP ⇒ in PLB aufnehmen f) PID (Prozessidentifikator), TID (Threadidentifikator), Zähler, Prioritäten
g) Adressen für Fehlerausgänge / Signale Division
durch 0
Ctrl C Ausnahme 3 Ausnahme 4 ... ...
Routine 1 Routine 2 Routine 3 ... ... ...
Erzeuger (Nachrichten erzeugen) Beobachter - KettenNT: Programmausnahmen in Betriebssystem integriert
f) Kosten für Betriebsmittel: CPU, Plattenzugriffe mit notieren.Belegte Betriebsmittel notieren, ggf. freigeben.
Beispiel : Microsoft Windows-NT: Prozesse und Threads beschreiben [14]
Process ID
Security Descriptor Base priority
Default processor affinity Quota limits
Execution time I/O counters
VM operation counters Exception/debugging ports Exit status
Thread ID Thread context Dynamic priority Base priority
Thread processor affinity Thread execution time Alert status
Suspension count Impersonation token Termination port Thread exit status
2.3. Entstehen und Vergehen von Prozessen bzw. Threads
• Anlauf des Betriebssystem: Mindestens einen Prozess starten. Prozessrechner - Betriebssysteme einfacher Art starten alle Prozesse bei Systemanlauf.
• Aus dem Prozessgeschehen heraus (z.B. UNIX) dynamisch.
fork fork
Baumstruktur
2.4. Prozesszustände und Übergänge
Nicht vorhanden Zombi
Zustand WAIT
wartend
READY bereit RUN
laufend
TCB bei Ereignisverwaltung
TCB´s in Ready-Queue Aktuelle TCB´s
Code
Zustände:
• RUN - laufend
Der (leichtgewichtige) Prozess hat die CPU
#Prozesse <= #CPU´s
Der TCB ist der aktuelle TCP (Einprozessorsyteme)
Gerade laufende Interrupt oder Systemaufrufe ändern daran höchstens indirekt etwas.
Viele Betriebssysteme
KERNEL RUN -KERNEL
RUN - USER USER
return call
• READY - bereit:
Der Prozess hat alle benötigten Betriebsmittel außer der CPU Der TCB hängt in der Ready-Queue
Der Prozess läuft nur deshalb nicht, weil ihm der Scheduler (Ablaufsteuerung) die CPU nicht zuteilt.
• WAIT - wartend
Der Prozess wartet auf ein Ereignis:
⇒ Ende einer I/O - Operation
⇒ Zeitgeber
⇒ Signal von anderen Prozess
Der Prozess braucht (im Normalfall) keine CPU - Zeit TCB → Ereignissteuerung
Der Prozess kann nicht laufen, auch wenn er die CPU zugeteilt bekommt.
Übergänge
• Nicht vorhanden → bereit:
UNIX-fork() erzeugt einen neuen Prozess. Der TCB wird angelegt - initialisiert.
Programmcode ggf. laden, Adressraum aufbauen
Registersatz gemäß den jeweiligen Konventionen aufbauen
• Laufend → bereit:
a) Der Scheduler entzieht dem Prozess die CPU preemptive; „gewaltsamer Entzug“
der CPU;
Vorkehrungen gegen Unterbrechung dringend erforderlich; UNIX, NT, Win95 b) Freiwillige Aufgabe der CPU durch „Yield-Aufruf“ non - preemptive;
Vorkehrungen gegen
Unterbrechung nicht erforderlich; Windows 3.1
• Bereit → laufend:
Das Betriebssystem lädt die erforderlichen Register aus dem TCB TCB → aktuellen TCB (Einrechnersystem)
KERNEL RUN -KERNEL RUN - USER USER
Sleep(...);
call, read
• Laufend → wartend:
Prozesse versetzen sich selbst in diesen Zustand, z. B. während des Aufrufs einer E/A - Routine.
TCB → Ereignissteuerung.
TCB´s Ereignisse
TCB → Scheduler
Hardware Interrupt
Interruptroutine
• Wartend → bereit:
Die Ereignissteuerung wird von einem externen (Hardware - Interrupt) oder internes Ereignis informiert: Der TCB muss gefunden werden.
Bei vielen Betriebssystemen laufen diese Routinen in ISR´s (Interrupt-Service- Routinen) ab.
Solaris User Level Threads [14]
Stop
Stop Sleep
Dispatch Stop
Wakeup Continue
Preempt
Stopped
Runnable
Active
Sleeping
Solaris Lightweighted Processes [14]
Timeslice or Preempt
Wakeup
Stop Blocking
System Call
Wakeup Dispatch
Runnable
Running
Active
Stopped
Continue
Stop
Beispiel : Microsoft-Windows-NT [14]
Resource Available
Unblock/Resume Resource Available
Unblock
Resource Not Available
Block/
Suspend
Terminate Switch
Pick to Run
Preempted
Transition Waiting Terminated
Not Runnable Runnable
Ready
Standby
Running
2.5. Umsetzung von Interrupts in Softwareereignisse
Hardware
• Interrupt aufnehmen, u. U. Schnittstellenkarte programmieren
• Interrupt puffern
• Sicherung von Flags und Befehlsregistern
Tastatur
Serielle Schnittstelle Interruptvektortabelle
Software
• Sicherung aller Register
• ggf. Stack umladen
• ggf. Suche nach dem Gerät, das den Interrupt ausgelöst hat
• Interrupt - Polling: Abfrageketten für Hardware - Interrupts
• Umwandeln von Hardwareinformationen in Nachricht:
Skizze:
Betriebssystem: Viele Baugruppen müssen ISR´s aussperren! Deswegen gibt es bei vielen Betriebssystemen erhebliche Reaktionszeiten bei Interrupts. Reaktionszeit
>= max. Zeit für exklusive Bearbeitung im Betriebssystem.
Problematik der Interruptbearbeitung:
1. Wie lange dauert die Reaktion des Systems? - Interruptbearbeitung: u. U. Aufsammeln von Anforderungen (= DPC =Deferred Procedure Call) ⇒ unklar, wann der Interrupt im Rechner (Betriebssystem) läuft ⇒ ∆t für Reaktion relativ hoch - Vorsicht auch bei Aussperren von Interrupts ⇒ ∆t für Reaktion relativ hoch
2. Umschaltung wartend → bereit: - kalkulierbar und sehr gering
3. Umschaltung bereit → laufend: - es muss berechenbar sein, wann ein Prozess die CPU erhält
Begriffe:
• Harte Echtzeitanforderung: Flugzeug, Militär (MIL-Normen)
• Weiche Echtzeitanforderung: Kaffeeautomat in 99,99% aller Fälle werden die Anforderungen eingehalten; wesentlich effizienter
Register sichern
ISR (Interrupt-Service-Routine)
Controller
⇒ Daten des Betriebssystem werden verändert!
Softwarepufferung des Interrupts?
Call Routineen des Betriebssystem z.B. Sende Tastaturereignis an Adresse XXXXX
2.6. Struktur von Betriebssystemen
2.6.1. Monolitische Struktur [17]
Das Betriebssystem ist dabei ein zusammengebundenes Stück Software, d.h. es besteht aus einer Menge von Prozeduren, von denen jede Prozedur jede andere aufrufen kann. Es gibt dabei eine Funktionsblockzerlegung in Dateisystem, Prozessverwaltung und Speicherverwaltung, sowie allgemeine Hilfsfunktionen (z. B. memcopy, stringcopy). Die so vom Betriebssystem bereitgestellten Dienste können dann mittels eines Supervisor Call (=
Kernaufruf) aufgerufen werden.
USER
KERNEL read
Prozeß vertagt SVC
return return
ggf. sleep Funktion
Dauer des Aufrufs
Unterverteiler Verteiler
Ablauf eines Auftrags an das Betriebssystem (SVC = Supervisor Call):
Eigenschaften:
• effizient
• im Grundsatz nicht netzwerkfähig
• Testaufwand wegen fehlender Modularität erheblich
• Klassischer Betriebssystemaufbau (Großrechner, UNIX, DOS, WIN) 2.6.2. Client-Server [17]
Das Betriebssystem besteht dabei aus:
• einem kleinen Kern: Interruptbehandlung, systemnahe Routinen
• einer Vielzahl von kleinen Prozessen: Uhr, Treiberprozesse, Dateisystem, Shell usw.
⇒ Das Betriebssystem besteht aus vielen, leicht tastbaren Modulen.
Ablauf eines Auftrags an das Betriebssystem:
USER
→ read
Datei- system
Treiber-
prozeß Treiber-
prozeß
Datei- system
USER
Prozeßwechsel 2x
Prozeßwechsel Prozeßwechsel
Prozeßwechsel Prozeßwechsel
Eigenschaften:
• wenig effizient, wegen häufigen Prozesswechsel (serieller Plattentreiber?)
• Netzwerkfähig
• Sehr gute Testbarkeit und damit höhere Sicherheit
• Flexibel
Moderne Betriebssysteme: Vereinigung beider Systeme.
2.6.3. Virtuelle Maschinen [12, 14,16]
Entwickelt in den 60er Jahren von IBM für Großrechner.
Ziel: Verschiedene Betriebssysteme auf einem Rechner.
Editor Buchung Adressen BATCH BATCH BATCH
CMS CMS CMS VM/370
Hardware
CMS = Conversational Monitoring System: Interaktives Betriebssystem Microsoft -Terminologie: HAL = Hardware Abstraction Layer.
Trends aus 1998
VMWare : Als Zusatz zu Linux bzw. Windows NT erhältlich. Damit laufen andere BSe unter dem jeweiligen BS im Fenster.
2.7. Ablaufsteuerung: Scheduling
Welche(r) Prozess(e) darf (dürfen) rechnen?
2.7.1. Ziele [vgl. 16, 17]
• jeder Prozess soll angemessen CPU - Zeit erhalten
• die CPU soll maximal ausgelastet werden
• die Antwortzeiten sollen kurz sein
• der Durchsatz bei Batch-Jobs soll hoch sein
• die Antwortzeiten auf Batch-Jobs sollen kurz sein
Die einzelnen Forderungen stehen teilweise in Widerspruch. Man kann sogar beweisen, dass Vorteile bei einzelnen Punkten Nachteile bei anderen mit sich bringen.
2.7.2. Lösungen
2.7.2.1. Kooperatives Multitasking
• Jeder Prozess darf rechnen, solange er will
• Es gibt keine erzwungenen Prozessumschaltungen
• Hilfsmittel: freiwillige Abgabe der CPU (yield)
• Beispiel: Windows 3.0 und 3.1
Problem: Einzelne Tasks können die CPU blockieren Vorteile:
• Unnötige CPU - Umschaltungen werden vermieden
• Prozesse brauchen keine Vorkehrungen (Synchronisation) gegen ungewollte Unter- brechungen treffen
Zeitscheiben
• Jeder Prozess erhält die CPU nur für eine bestimmte Zeit: Zeitscheibe (Time Slice). Nach Ablauf der Zeitscheibe wird die CPU entzogen.
• Vorteil: Jeder Prozess erhält nach einer gewissen Zeit die CPU (#Prozesse * Länge Zeitscheibe)
• Nachteil: Langläufer (z.B. „Apfelmännchen“) werden gegenüber Prozessen, die die CPU wenig benutzen (z.B. „vi“) zusätzlich bevorzugt.
2.7.2.2. Prioritätssteuerung
• Die Prozesse erhalten Prioritäten: statische Prioritäten.
• Es darf derjenige Prozess (Monoprozessorsystem) mit der höchsten Priorität, der am längsten gewartet hat rechnen.
• Vorteil: Dringende Aufgaben können an Prozess mit hoher Priorität vergeben werden. Ihr Ablauf innerhalb gewisser Zeit kann so absolut sichergestellt werden.
• Nachteil: kein faires Scheduling
2.7.2.3. Kombinationslösung: Prioritätssteuerung mit Zeitscheiben:
Eigenschaften:
- Wegen Prioritäten immer noch kein faires Scheduling gewährleistet.
- Zusätzlich zu statischen Prioritäten wird eine dynamische Priorität eingeführt - Diese wird vom Betriebssystem innerhalb gewisser Schranken (NT m 2) verändert
2.7.2.4. Shortest Job First
Ziel: Kurze und mittlere Bearbeitungszeiten.
Voraussetzung: Die Laufzeiten einzelner Prozesse sind bekannt (Batch-Betrieb)
Reihenfolge: Der Prozess mit der längsten Laufzeit rechnet zuerst (bei nicht gleichzeitiger Ankunft: Restlaufzeit).
Prozess: a b c d
Zeitablauf: 8 4 4 4
Ankunft aller Prozesse zum Zeitpunkt 0.
Reihenfolge: a b c d
Zeit 20
18 16 14 12 10 8 6 4 2 0
8 12
16 20
⇒ 8+12+16+20 = 56
⇒ im Mittel: 56/4 = 14
Zeit 20
18 16 14 12 10 8 6 4 2 0
20
⇒ 4+8+12+20 = 44
⇒ im Mittel: 44/4 = 11 Shortest-Job-First Reihenfolge: b c d a
2 8
12
Verweilzeiten für 4 Prozesse mit Bearbeitungszeiten T0, T1, T2, T3: T0
+ T0 + T1
+ T0 + T1 + T2
+ T0 + T1 + T2 + T3
= 4 T0 + 3 T1 + 2 T2 + T3
Allgemein für n Prozesse:
n T0 + (n-1) T1 + ... + Tn-1 Minimierung durch Anordnung:
T0≤ T1≤ T2≤ ... ≤ Tn-1
= Shortest-Job-First“
⇒ Minimale mittlere Verweilzeit
2.7.2.5. Praktische Systeme: Beispiel 1: VAX - CPU - Zuteilung:
Kann nicht unterschritten werden
0 16 31
Echtzeitprozesse
Statische Priorität
Bonus Anlauf
Multilevelfeedback (MLF-Verfahren). Schemata zur dynamischen Reduktion der Prioritäten.
Oft bis Priorität = 0 zum Schutz vor Endlosschleifen.
1 Idle
norm al 16 hoch
31
Echtzeitkonstante
2.7.2.6. Scheduling unter NT [13]
Das Quantum ist ein Zeitintervall, das jedem Thread zugeteilt wird. Jeder Thread erhält einen Quantum-Wert beim Start. Für NT WS: 6, für NT Server 36. Jede Unterbrechung des Taktgebers subtrahiert einen fixen wert (3) vom Quantum. Die Länge dieses Quantums variiert mit der Hardware-Plattform. Bei Intel-Rechnern beträgt das Quantum 15 ms, bei Dec- Alpha-Rechnern beträgt es 7,8125 ms.
Windows NT 4.0 benutzt vier Typen der Scheduling-Anpassung:
• temporäre Verlängerung des Quantums der Threads im Vordergrundprozess
• temporäre Prioritätssteigerung bei Beendigung des Wartezustands
• temporäre Prioritätssteigerung bei Threads, die keine Prozessorzeit zugeteilt bekommen Verlängerung des Quantums
Die Verlängerung des Quantums betrifft nur interaktive Prozesse bei NT WS, die im Vordergrund laufen. Das Quantum kann damit von 6 auf 12 bzw. auf 18 erhöht werden.
Prioritätssteigerung
Die temporäre Prioritätssteigerung bei Beendigung des Wartezustands dient dazu, Die Reaktionszeit von Threads zu verkürzen. Sie kann nie bis in den Echtzeitbereich reichen.
Diese Steigerung kann durch die Gerätetreiber bei Warten auf E/A, aber auch durch den Kernel bei Warten auf Interaktion vom Benutzer erfolgen.
Prioritätssteigerung bei Hungertod (Auch Prioritätsinversion):
Problem: Ein Thread mit Priorität 11 wartet auf eine Ressource, die von einem Thread mit Priorität 4 belegt wird. Aber ein Thread mit Priorität 7 hindert den Thread mit Priorität 4 am Arbeitsfortschritt, sodass der Thread mit Priorität 11 de fakto nicht den Vorrang vor dem Thread mit der Priorität 4 erhält.
Lösungsansatz unter NT: Der Thread „Balace Set Manager“ durchsucht die Ready-Queues nach Threads, die lange darin verweilen (3 bis 4 Sec). Dann wird deren Priorität einmalig auf 15 angehoben und das Quantum verdoppelt. Danach: Rückfall auf die Basispriorität.
2.7.2.7. Scheduling unter UNIX Literatur: [1]
UNIX unterscheidet zwischen System- und Benutzerprioritäten.
127
B enutzer 0
-128
SY STEM
Sw apper, Platten I/O , w arten auf Puffer, auf T T Y , auf E xit
Statische Priorität + M alus (zeitabhängig)
= Priorität V
o r r a n
g B enutzer
Die Prioritäten „Swapper“, „Warten auf Platten-I/O“, „Warten auf Puffer“ und Warten auf inode“ sind hohe, nicht unterbrechbare Systemprioritäten. „Warten auf exit-KindProzess“ ist eine niedrige, unterbrechbare Systempriorität. UNIX ordnet jedem Prozess, der in den Zustand „WAIT“ übergeht (sleep()), eine mit der Ursache des Schlafs zusammenhängende Priorität zu. Ein Prozess, der auf Beendigung einer Platten-I/O wartet, hat eine höherer Priorität als ein Prozess, der auf einen Puffer wartet (er hat bereits einen Puffer, also besteht die Aussicht, dass er weiterarbeiten kann, um dann BM Æ Puffer freizugeben, auf die andere Prozesse warten, deren Anlauf also sinnlos wäre). Nach Wechsel in den Benutzerzustand wird seine Priorität wieder berichtigt.
Ermittlung der dynamischen Priorität im Benutzerzustand
• Der Malus wird einmal pro Sekunde ermittelt
• CPU - Feld im TCB der Prozesse = Anfangspriorität. Anfangswert: 0
• 60 x pro Sekunde: CPU - Feld des rechnenden Prozesses wird um 1 erhöht = Malus
• Neue Berechnung der Prioritäten:
- CPU - Feld* := CPU-Feld/2 (Die Hälfte der Strafe wird vergessen) - dynamische Priorität := statische Priorität + CPU-Feld*/2
Beispiel:
Prozesse A, B, C (in dieser Reihenfolge) mit statischer Priorität 60 ohne Berücksichtigung der Zeitscheiben.
0 sec. 1 sec. 2 sec. 3 sec.
A: dynam. Prio.
CPU - Feld
60 RUN 0 ...
60
75 1)
READY 30 ...
30
67 2)
READY 15 ...
15
63 3) RUN 7 ... 67
B: dynam. Prio.
CPU - Feld 60 READY 0 ...
60
60 RUN 0 ...
60
75 1)
READY 30 ...
30
67 2)
READY 15 ...
15 C: dynam. Prio.
CPU - Feld 60 READY 0 ...
60
60 READY 0 ...
60
60 RUN 0 ...
60
75 1)
READY 30 ...
30
1) 60 + ((60/2)/2) = 60 + 30/2 = 75
2) 60 + ((30/2)/2) = 60 + 15/2 = 67
3) 60 + ((15/2)/2) = 60 + 7/2 = 63 Wie wirkt sich der Malus aus?
Versuch: Bestimmung des maximalen Malus.
CPU(i) untersuchen: Langläufer hoher Priorität
0 1 2 3 4 5 0 ...
60
30 ...90
45 ...
105
52 ...
112
56 ...
116
58 ...
118 CPU(i) = 60 + 60 * ½ + 60 * ¼ + 60 * 1/8 + ... + 60 * 2 -i
= 60 * (1+ ... + 2 -i) ≤ 120
Vergessensfaktor a = 0,5 n. Im Allgemeinen: 0 ≤ a ≤ 1.
Betriebssystem regelt a je nach Systemlast, bei kleiner Last ist a klein.
2.7.2.8. Beispiel: Microware OS/9- System = UNIX - Klone mit Echtzeitfähigkeit
• Nach Ablauf jeder Zeitscheibe wird die dynamische Priorität jedes bereiten Prozesses um 1 erhöht (= Aging)
• Bei Verdrängung: Rückfall auf die statische Priorität
• Aging ist beschränkt, damit systemkritische Anwendungen oberhalb dieser Schranke laufen können.
Prozeß A
t 100
P 103
rechnend Prozeß B bereit
Prozess A mit Priorität 100 und Prozess B mit Priorität 103. Höhere Priorität hat Vorrang, unter der Annahme, dass bei gleicher Priorität die längere Wartezeit entscheidet.
≤2
3. Prozesskommunikation, Synchronisation
3.1. Wettrennen (race-Condition), kritische Gebiete
Beispiel 1
Ein Druckerspooler verwaltet Aufträge ⇒ Verwalte die Dateinamen in Array
Eintragen (Dateiname); Feld(i++)=Dateiname;
xyz Name 3
Name 2 Name 1
i i++
Eintragen(xyz);
1. Eintragen 2. Schalten von i Annahme
Datei eintragen zuerst dann i schalten. Verschiedene Prozesse können diese Schnittstelle aufrufen.
Szenario
1. Tasks X, Y werden drucken
2. X wird nach Eintrag in Drucker-Array unterbrochen 3. Y läuft durch
XXXXX
?
?
1) ?
i X hat einen Namen eingetragen YYYYY
? 2) ? ?
i Y hat einen Namen eingetragen X ist damit überschrieben YYYYY
?
?
3) ?
i Y hat i weitergeschaltet
YYYYY
?
?
4) ?
X hat i weitergeschaltet i
⇒ undefinierter Auftrag
X läuft wieder an.
Beispiel 2: Lineare Liste
z.B. Druckaufträge , etc.
Einzeigern geht in 2 Schritten vor sich : a alte Liste in Block
b Liste = Block 1 b 1 a
2 b 2 a
1 2 3
Ablauf : * 1 a ==> Interrupt ==> Schreiber 2 läuft : 2 a -> Listenzeiger auf 1 * 2 b -> Neuer Listenanfang
* dann : Schreiber 1 läuft weiter : 1 b setzt Blockanfang auf Auftrag ==> Kein Blockanfang für Auftrag 2 vorhanden : er wurde vergessen !!
Kritischer Abschnitt
Ein Abschnitt heißt dann kritisch , wenn es durch wechselseitige Zugriffe von verschiedenen Prozessen zu Dateninkonsistenz kommen kann.
Wettkampfbedingungen
Mehrere Prozesse greifen auf gemeinsame Daten lesend oder schreibend zu und deren Ergebnisse hängen vom Prozessfortschritt ab.
Gegenseitiger Ausschluß
Ein Verfahren , das anderen Prozessen den Zugriff auf gemeinsam genutzte Variablen / Dateien verwehrt , solange ein Prozess damit arbeitet.
Ein erster Versuch zur Lösung des Problems
int frei = 1; // frei = 0 = besetzt while (!frei)
; frei=0;
. // Kritisches Gebiet,
. // z.B. Schreiber/Schreiber
. // Problem
frei=1;
Anforderungen an Lösungen
• Wechselseitiger Ausschluß: Genau ein Prozess darf in seinem kritischen Abschnitt sein.
• Fortschritt: Wenn ein Prozess nicht auf Zugang zum kritischen Abschnitt wartet, dann darf er die darauf wartenden Prozesse nicht am Zugang hindern.
• Beschränktes Warten: kein auf Zugang wartender Prozess muss endlos warten Schichten der Prozesskommunikation:
CORBA: (Common Object Request Broker Architecture) RPC: (Remote Procedure Call)
COM
RMI Remote Method Invocation DDE: (Dynamic Data Exchange)
Software höherer
Ebene Monitore
Sleep / Wakeup
Semaphoren nach Dijkstra Send / Receive
Pipes
Ada: Rendezvous
Software mittlerer Ebene Sperren von Interrupts
Spezialfälle: Test and Set Peterson-Lösung
Hardware Keine kritischen
Abschnitte Unterbrechung
3.2. Kritische Abschnitte (Low Level, kurze kritische Abschnitte)
Lösung nach Peterson: [14, 16]
#define FALSE 0
#define TRUE 1
#define N 2 // Anzahl der Prozesse
int turn; // Wer ist an der Reihe?
int interested[2]; // Alle Werte sind anfangs 0 (FALSE)
void enter_region(int process) // process: wer tritt ein (0 od. 1) {
int other; // Nummer des anderen Prozesses other = 1-process; // Konkurrent des Prozesses interested[process]=TRUE; // Zeige dein Interesse turn = process; //setze Marke
while(turn==process && interested[other]==TRUE
; // leere Anweisung
}
void leave_region (int process)//process: wer verläßt (0 od. 1) {
interested[process]=FALSE; // gib dein Verlassen bekannt }
Szenario
[1]
[0]
Prozeß 1 Prozeß 0
interested
bereit laufend
0 0
0 turn
Laufend process=1;
other =0 process=0;
other=1 bereit 0
1 0
Im kritischen Gebiet
Im kritischen Gebiet
enter Im kritischen
Gebiet laufend 1
1 0
1 1
1
1 1
0
0 1
0
0 0
0
0 1
0
1 1
1
1 0
1 Im kritischen Gebiet
3.3. Hardwareunterstützte Lösungen
Monoprozessorsystem:
1. Interrupts sperren 2. arbeiten
3. Interrupts freigeben
Nur für sogenannte kurze kritische Abschnitte!
Multiprozessorsystem: Testen und Setzen als unteilbare Aktion Beispiel: 8086
mov al,1 ; nach Intel
loop: lock xchg flag, al ; Multiprozessorunteilbar test al, al
jnz loop
--- kritisches Gebiet --- mov flag, 0
oder:
- 68000, Großrechner: Testen und Setzen
- Pentium: CMPXCHG: Vergleich mit bedingtem Austausch - Motorola: TAS: Test and set
Forderungen
• Wechselseitiger Ausschluß
• Keine Annahmen über Geschwindigkeiten
• Endliche Wartezeiten
• Kein auf Zugang wartender Prozess darf andere Prozesse blockieren
3.4. Kritische Abschnitte - High Level
(= Lange kritische Abschnitte) 3.4.1. Sleep-Wakeup
Prozesse können mit Sleep(Zeit) für eine gewisse Zeit (kann auch unendlich sein) in den Zustand „Wartend“ versetzt werden. Andere Prozesse können wartende Prozesse per Wakeup wieder aktivieren.
Anwendung
if (Bedingung)
// Unterbrechung möglich ! wakeup
wakeup ist nicht nur aufwecken, sondern enthält indirekt auch die Nachricht „ein Ereignis ist eingetreten“
⇒ wakeups müssen gepuffert werden.
Prozeß A Prozeß B
puffern sleep wakeup
Busy polling
3.4.2. Semaphoren
Dijkstra schlug 1965 einen abstrakten Datentyp (Klasse) Semaphoren vor.
Skizze
Abschnitt kritischer
P: Passeren, Probeeren = Passieren, Probieren V: Vrijgeve, Velaat = Freigeben, Vertagt
Beschreibung
class Semaphore {
int Zaehler; // 0..n Anzahl der gleichzeitig in den kritische // Abschnitt eintretenden Prozesse vom Betriebssystem // verwaltet. Für n=1 binäre Semaphore.
public:
Semaphore(int Anfangswert) // Anfangswert = Zaehler void P(); // Testen und vertagen wenn nicht frei void V(); // Vertagen
};
P - Operation
Als unteilbare Operation (Aktion) im Betriebssystem implementiert.
if (Zaehler > 0) // z.B. 1 bei binärer Semaphore Zaehler--;
else
V(); // Prozess vertagen → Sleep
V - Operation
Als unteilbare Operation (Aktion) im Betriebssystem implementiert.
Zaehler++;
if (ein Prozess wartet)
wähle einen wartenden Prozess aus wakeup auf diesen Prozess
Binäre Semaphore
Zu einem Zeitpunkt ist maximal eine P - Operation erfolgreich!
Beispiel: Erzeuger/Verbraucher-Kopplung [16]
#define N 100
typedef int semaphore; // Semaphore sind spezielle int-Variablen
semaphore mutex = 1; // kontrolliert Eintritt in kritischen Bereich semaphore empty = N; // zählt die leeren Puffereinträge
semaphore full = 0; // zählt die belegten Puffereinträge, Anfangswert
void producer() {
while(1) // Endlosschleife {
Produziere(Satz); // Erzeugt einen Eintrag P(empty); // warte auf leeren Satz
P(mutex); // verriegle kritischen Abschnitt Eintragen(Satz); // neuen Eintrag in Puffer einfügen V(mutex); // Ende kritischer Abschnitt
V(full); // Signal: voller Satz }
}
void consumer() {
while(1) //Endlosschleife {
P(full); // warte auf vollen Satz
P(mutex); // verriegle kritischen Abschnitt Austragen(Satz); // entnimm Eintrag
V(mutex); // Ende kritischer Abschnitt V(empty); // Signal: leerer Satz Konsumiere(Satz); // verbrauche Satz }
}
Zur Kopplung
Consumer Producer
V(empty);
V(full);
P(full); Warten auf Datensätze P(empty); Warten auf leere Stellen
Beispiel 2: Fünf Philosophen [16]
Ein Philosoph denkt, wird hungrig, will essen.
Jeder Philosoph braucht zum Essen zwei Gabeln, eine zu seiner Linken und eine zu seiner Rechten.
Problem: Eine Zugangsregelung, bei der kein Philosoph verhungert.
Erster Lösungsansatz
void Philosoph (int nr) // nr = 0,1,2,3,4 Nr. des Philosophen { while (1) // Endlosschleife
{
Denken();
// Hunger
NimmGabel(links(nr));
NimmGabel(rechts(nr));
// essen
LegeGabel(links(nr));
LegeGabel(rechts(nr));
} }
Problem: Unterbrechungen können dazu führen, dass jeder Philosoph genau eine Gabel erhält.
Zweiter Lösungsansatz Idee:
• Alle benötigten Gabeln belegen oder keine Gabel belegen
• Für jeden Philosophen einen „Warteplatz“ vorsehen ( Anfangszustand = gesperrt). Vom Verwaltungssystem aus freischalten.
• ABER: Verwaltungssystem benötigt exklusiven Zugriff (binäre Semaphore) Programm
#define N 5 // Anzahl der Philosophen // Zustände der Philosophen:
#define THINKING 0
#define HUNGRY 1
#define EATING 2 // Nachbarn:
#define RIGHT ((i+1)%N)
#define LEFT ((i-1)%N)
// Verwaltung:
void Test(int i)
{ if ((GetState(i) == HUNGRY) && (GetState(LEFT)!= EATING) &&
(GetState(RIGHT)!= EATING)) { SetState(i, EATING);
V(i); } // Freischalten }
void NimmGabeln(int i)
{ P(mutex); // verriegle Verwaltung; mutex: binäre Semaphore, // Anfangswert 1
SetState(i, HUNGRY);
Test(i);
V(mutex); // Verlasse kritischen Bereich P(i); // i-te Semaphore frei
}
void LegeGabeln(int i)
{ P(mutex); // Eintritt in den kritischen Bereich SetState(i, THINKING); // Philosoph hat essen beendet Test(LEFT); // Teste ob linker Nachbar jetzt essen kann Test(RIGHT; // Teste ob rechter Nachbar jetzt essen kann V(i); // kritischen Bereich verlassen
}
void Philosoph (int i)
{ while(1) // Endlosschleife { denke(i);
NimmGabeln(i); // Nimm beide Gabeln oder blockiere essen(i);
LegeGabeln(i);
} }
Probelauf
03 1 0 1 mutex
Status
H E H3
T E H E T
T E H E T
T H1 H E T
T T H E T
T T T T T
0 1 2 3 4
3 EATING
* vertagen
frei wartemd
Test2 Test3
*
Läuft*
0 1 2 3 4
Prozeß 2 wartet
13
0 01 0* 0 0
0 11 0* 0 0
0 0 0* 0 0
0 0 0* 0 0
0 0 0 0 0
0 1 2 3 4
Philosophen Semaphoren
Anfang:
12
02 erfolglos
1 0 0 1
Wichtig: Dieses Protokoll garantiert nicht, dass eine Anforderung nach endlicher Zeit erfüllt wird (Überholvorgänge möglich). Sichergestellt ist dagegen die maximale Parallelität.
Leser / Schreiber - Problem
Kritischer Bereich
Leser: keine Änderung;
N Leser gleichzeitig möglich
Schreiber: exklusiver Zugang
Zu einem Zeitpunkt können beliebig viele Leser, aber nur ein Schreiber im kritischen Bereich sein.
Shared Memory mit Semaphoren
Semaphoren kapseln der Schreibzugriffe
Prozeß B Prozeß A
memory shared
Gemeinsamer Speicher für 2 Globale Systemresource
„Hinzufügen“
attach
„Entfernen“
detach
Vorteile
• Aktives Warten wird vermieden
• Weit verbreitet Nachteile
• Fehleranfälliges Konzept
• Kein Transport von Nachrichten
3.4.3. Send / Receive
Die Prozesse schicken sich gegenseitig Nachrichten. [16]
Adressen
• Briefkasten oder
• Prozess
send (Briefkasten, Nachricht);
receive (Briefkasten, Nachricht);
→ blockieren (warten bei leeren Briefkaten)
→ nicht blockieren (Rückkehr zum Aufrufer auch bei leeren Briefkasten) Beispiel
Semaphoren lassen sich über Send / Receive realisieren.
Implementierung:
• Semaphore = Briefkasten
• Anfangszustand : Auffüllen (send) mit #Anfangswert Nachrichten
• P : receive
• V : send Vorteile
• Aktives Warten wird vermieden
• Mehrrechnerfähig Nachteile
• Keine automatischen Quittungen
• Pufferüberlauf möglich
• Überholvorgänge von Nachrichten möglich Problem bei heterogenen Rechnersystemen
Datenformate bei verschiedenen Rechnern unterschiedlich.
Little-Endian < = > Big-Endian Pipes unter UNIX
Bei UNIX meist 5120 Byte
lesen schreiben
Varianten
• Unbenannte Pipes:
Übergabe bei fork()
• Benannte Pipes:
Namen im Dateikatalog, z.B. Basiskommunikation unter NT4.0:
NT4.0:\\Computer\Pipe-Name UNIX:
mknode - Kommando
ipcs - Kommando Status von Semaphoren
ipcrm - Kommando Remove von Semaphoren
3.5. Dateien und UNIX-fork(), exec
stdaux stdprn stderr stdout stdin
4 3 2 1 0
Vor Ablauf eines Prozesses eingestellt;
Nur DOS
Offene Dateien werden in der OFT (Open File Table) verwaltet. Der Zugriff im Programm erfolgt über Kennzahlen (Handle, Gerätenummer).
Wichtig
Gerätenummern liefern flexible Lösungen als festcodierte Dateien.
Aufrufe in C - Programmen:
int open(...); liefert erste freie Nummer im OFT int close(...); schließt eine Nummer im OFT int dup(int Gerätenummer); duplizieren einer Gerätenummer
Pipes in C anlegen:
int pipe (int *);
int Kennzahlen[2];
pipe(Kennzahlen);
read / write auf pipe „wie auf Datei“ mit den gelieferten Kennzahlen
Pipe 5120 byte
Kennzahl[0]
⇒ lesen Kennzahl[1]
⇒ schreiben
Wichtig
Lesen bei leerer Pipe
- Bei vorhandenen Schreiber: warten - Bei nicht vorhandenen Schreiber: EOF Schreiben bei voller Pipe
- Bei vorhandenen Leser: warten
- Bei nicht vorhandenen Leser: generell bei Schreiben ohne Leser → Signal Bei diesen unbenannten Pipes sind alle Leser und Schreiber bei UNIX registriert:
• pipe - Aufruf Leser + Schreiber
• dup Leser oder Schreiber registrieren
• fork() Klonen von allen Einträgen der OFT - auch Pipekennzahlen.
0 1
lesen schreiben
Anwendungen
Beispiel 1: sort < abc
Beispiel: ps -ef | grep ‘abc’
Lösungsmöglichkeit DOS:
1. ps -ef > datei 2. grep ‘abc’ < datei 3. datei löschen
Vorteil: einfach Nachteil:
- Tasks seriell
- schlechtere Performance wegen Dateibenutzung („Stau an Dateikatalog“) 21
0
stderr stdout stdin
21 0
stderr stdout stdin
21 0
stderr stdout stdin
wait
Soll sort anwenden, bei 0 ‘abc’
shell Kind Eltern
fertig
exec (‘sort’ ...);
1. Schritt: close(0);
Realisierung
21 0
stderr stdout stdin
21 0
stderr
stdout abc Änderung
an OFT
Lösungsmöglichkeit UNIX:
stderr stdoutstdin
stderr stdoutstdin
stderr stdoutstdin
*
Eigentliche shell
Ziel: grep Ziel: ps
shell
Kind Eltern
fork()
dup-Schreiben ‘Pipe’
close stdout close-Lesen ‘Pipe’
* Pipe müßte vorher aufgemacht werden Close-Lesen ‘Pipe’
Close-Schreiben ‘Pipe’
...
ps läuft exec ‘’ps’’
...
grep läuft exec ‘’grep’’
dup-lesen ‘Pipe’
close stdin
close-Schreiben ‘Pipe’
3.5.1. Event-Variable :
(Reed und Kanodia , 1974) Ziel : faire ZugangsregelungBeispiel : KFZ-Zulassungsstelle : Kartenautomat vergibt sequentiell Nummern Zugangsprotokoll :
a) Nummer ziehen
b) Warten bis Nummer dran ist
Eventvariablen sind Variablen mit 4 Operationen :
1. int ticket ( ) : liefert laufende Nummer und schaltet um eine Nummer weiter 2. wait (E,n) : Warten , bis Wert der Event-Variable E ≥ n
3. advance (E) : Schalte Wert von E
4. int read (E) : Auslesen des Wertes von E ohne warten Zum obigen Beispiel Zulassungsstelle :
Client : 1 Eventvariable E
Kunden führen N = ticket () , wait (E,N) aus Dienstleister : Wenn bereit , advance (E)
Vorsicht ! Event - Varable gibt es in vielen Variationen ! 3.5.2. Socket - Konzept
öffne Verbindung Verbindung
bearbeiten Warte auf Verbindung Bietet Dienst an
Port als Kommunikationsendpunkt
Rechnername + Port
Streamorientierte Verbindung Einrichten: Portnummer
Bietet Dienste an
Nummern (ports): 1, ..., 80 ⇒ http
Client Server
Eingangsstrom Eingangsstrom Ausgangsstrom
Ausgangsstrom
3.5.3. Ada: Rendezvous
Problem bei Send / Receive: Asynchroner Lauf der Beteiligten ⇒ Pufferüberlauf, Überholvorgänge
Deswegen: Rendezvous - Konzept (C.A. Hoare):
Sender
Empfänge
Synchron
3.5.4. Dynamic Data Exchange (DDE) von Microsoft Ziel
• Nachrichtenaustausch
• Abonnieren von News Realisierung
• Die Prozesse laufen asynchron
• Beruht auf Send / Receive
Namen: WM_DDE_* (Alle Meldungen beginnen mit WM_DDE_
Hot Link
Daten immer bei Änderung
Warm Link Daten immer bei Änderung
aber nur auf Anforderung Cold Link
Daten nur auf Anforderung Server
TERMINATE TERMINATE
Optional ACK
DATA REQUEST
ACK INITIATE
Client Client Server Client Server
ACK UNADVISE
ACK
ACK ADVISE
ACK INITIATE
TERMINATE TERMINATE
DATA Staugefahr!
ACK UNADVISE
ACK
ACK ADVISE
ACK INITIATE
TERMINATE TERMINATE
DATA ohne Daten REQUEST
DATA OptionalACK
3.5.5. Monitore
Entwicklung durch C.A. Hoare. Änderungen durch Lampson / Redell (Xerox) → Java [14]
Prinzip:
• wait()
• signal() Monitor Daten &
Funktionen
Zu einem Zeitpunkt ist höchstens 1 Prozeß drin P1 muß
warten
Tor: spezielle Funktionen
wait(): Der Aufrufer wartet. Er „verläßt“ den Monitor
signal(): Ein wartender Prozess - wait() - wird aktiviert
→ ist im Monitor. Deswegen: Aufrufer muss Monitor sofort verlassen.
Verbesserung:
Aufgeweckte Prozesse werden nicht automatisch im Monitor aktiviert. Er muss mit den anderen Prozessen um den Zugang konkurrieren.
ALT: if (keine Ressourcen da) wait();
NEU: while (keine Ressourcen da)
wait(); // ⇒ kein aktives Warten!
In Java:
class Erzeuger_Verbraucher {
public: synchronized Typ get Ressource() {}
// mit synchronized wird ein Monitor erzeugt.
} wait();
xyz.notify(); // einen schlafenden Prozess wecken xyz.notifyAll(); // alle schlafenden Prozesse wecken
3.5.6. Remote Procedure Call (RPC)
Entwicklung von NFS (Network File System) bei SUN Einsatzgebiet: SAP/R3 - Anbindungen (RFC)
Prinzip
Prozeß wartet
auspacken
Stellvertreter print(’’abc’’);
Server Client
abc abc
Prozeß
benachrichtigen print(’’abc’’);
Lokale Darstellung Ereignisse SEND NDR
SEND NT: benannte Pipes NDR -Transformation
3.5.7. Remote Method Invocation (rmi) NUR Java!
Der Client ruft Methoden, z. B. Datenbankanwendung auf dem Server auf.
3.5.8. CORBA
( Common Object Request Broker Architecture)
• Derzeitige Version : 2.0
• ab Netscape Communicator 4.0 eingebaut
• Unabhängig von Sprachen und Rechnern: COBOL, C, C++, Java, Smaltalk
• Prozesskommunikation ist gekapselt
Skizze:
Analog RPC
Kommunikationsendpunkt z.B. Socket
Database.getpreis(xyz);
Thread
In heterogener Umgebung
Client Server
(außer oneway) blockierend
4. Deadlocks - Systemverklemmung
Beispiele:
- Fünf Philosophen: Jeder benutzt die rechte Gabel
- Zwei Personen A, B brauchen jeweils Drucker und Plotter.
-
Plotter belegen
Drucker belegen B
A Drucker anfordern
Plotter anfordern
⇒ Deadlock
- kreisförmige Wartesituation im Verkehr:
-
- Ein Subsystem besteht aus 1 ElternProzess und 10 Kindprozessen. Das Subsystem kann seine Arbeit nur dann verrichten, wenn alle 11 Prozesse gleichzeitig laufen. Im BS können (Annahme) maximal 100 Prozesse laufen.
- Annahmen: - Das Subsystem wird 10 mal gestartet - Jedes Subsystem kann 1 Vater- und 9 Kindprozesse starten
=> Deadlock in Abhängigkeit von der Zeitlage!
Definition
Für eine endliche Menge M von Prozessen mit mindestens zwei Prozessen spricht man von einem Deadlock, wenn jeder Prozess aus M auf ein Signal eines anderen Prozesses aus M wartet.
4.1. Formale Beschreibung
Coffman zeigte 1971, dass ein Deadlock nur durch ein Zusammentreffen von vier Umständen eintreten kann:
1. Exklusives Belegen
2. Belegen und Warten (Prozesse warten mit belegten Betriebsmitteln) 3. Belegen bis zur Freigabe
4. Kreisförmige Wartesituation
Deadlocks müssen nicht zwangsweise auftreten: sporadische Fehler.
Das Zustandekommen hängt von den Zeitlagen einzelner Prozesse ab.
Graphische Darstellung:
Betriebsmittel Prozeß
belegt warten auf
Beispiel: 3 Prozesse A, B, C ; 3 Betriebsmittel r, s, t
C B
A A* B C
t s
r 6
5 4 3 2 1
t
belegt warten auf
s r
Zwei verschiedene Szenarios, wobei jeder Prozess zwei Betriebsmittel benötigt:
6 würde von UNIX nicht erfüllt
* A läuft an und gibt seine Betriebsmittel frei ⇒ B kann belegen und gibt dann wieder frei usw.
4.2. Maßnahmen gegen Deadlocks
Keine Maßnahmen:
Die Jagd nach Fehlern könnte an anderer Stelle sinnvoller sein.
Nicht bei Qualitätssoftware
Erkennen und Aufbrechen bzw. Verhindern:
UNIX: Das Dateisystem quittiert eine letzte Anforderung vor einer kreisförmigen Wartesituation mit Fehler.
Alternative: Blockierte Prozesse auf kreisförmige Wartesituation überprüfen und ggf.
Abbrechen eines oder mehrerer Prozesse.
c) Vermeiden von Deadlocks
Ansatz : 4 Kriterien nach Coffmann:
-> z.B. kreisförmige Wartesituation Idee:
Nummerieren aller Betriebsmittel
Belegen in der Reihenfolge der Nummerierung, also z.B. immer zuerst Drucker, dann Plotter Hier: Funktion gut (siehe Beispiel oben)
Aber: Nicht überall anwendbar (Dateien, Prozesse) -> z.B. belegen und warten
Anfordern mehrerer Betriebsmittel auf einmal (z.B. NT: WaitForMultipleObjects)
Szenario:
Prozeß wartet, u.U. belegen andere Prozesse einzelne Betriebsmittel während des Wartens.
=> Überholvorgänge sind möglich
=> Endloses Warten auf Zugang
4.3. Bankiers - Algorithmus nach Dijkstra
Betriebsmittel:
Geld einer Bank, wird von einem Bankier an die beteiligten Personen zugeteilt.
Beteiligte Personen:
Bekannt: Bisher benutzte Kredite Beantragte Kredite
= Gesamtkredit
Rückzahlung erst, wenn Gesamtkredit gewährt Rückzahlung ohne Zinsen in vollen Betrag Szenario:
Kunden: a b c d
bisher gewährte Kredite 1 1 2 4
Gesamtkredite (max. Wunsch) 6 5 4 7
=> Beantragte Kredite (noch nicht erfüllt) 5 4 2 3 Annahme: Die Bank hat noch 2 Einheiten Geld.
Problem:
Gibt es eine Reihenfolge der Zuteilungen (incl. Rückzahlung), bei der alle Wünsche erfüllt werden können?
Definition:
Ein System heißt sicher, wenn es eine solche Reihenfolge der Zuteilung gibt.
Wichtig:
Jeder Schritt (Zuteilung + Rückzahlung) erhöht die BM. Anforderungen können dann leichter erfüllt werden.
=> Kein Backtracking erforderlich Algorithmus:
Suche einen Kunden mit
Beantragte Kredite <= Restkapital Nicht gefunden: Deadlock! STOP!
Sonst: Zuteilung + Rückzahlung Solange bis alle Anforderungen erfüllt sind.