„Bankieralgorithmus“ – Versionsunterschied

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen
[ungesichtete Version][gesichtete Version]
Inhalt gelöscht Inhalt hinzugefügt
Voraussetzungen und Beschreibung zusammengeführt, Anwendung und Implementierung hinzugefügt, Beispiele umgebaut und ergänzt.
Zeile 23: Zeile 23:


== Implementierung ==
== Implementierung ==
Folgende [[Python (Programmiersprache) | Python]] Funktion implementiert den Bankieralgorithmus:
Folgende [[Python (Programmiersprache)|Python]] Funktion implementiert den Bankieralgorithmus:
In einer Liste werden alle terminierten Prozesse gesammelt. Solange diese Liste noch nicht alle Prozesse enthält und keine Verklemmung aufgetreten ist werden die Anforderungen aller noch nicht bearbeiteten Prozesse untersucht.
In einer Liste werden alle terminierten Prozesse gesammelt. Solange diese Liste noch nicht alle Prozesse enthält und keine Verklemmung aufgetreten ist werden die Anforderungen aller noch nicht bearbeiteten Prozesse untersucht.
Können alle benötigten Ressourcen eines Prozesses durch die noch verfügbaren Ressourcen abgedeckt werden (elementweise <math>R_i \le A</math>), so wird dieser Prozess abgearbeitet und seine Ressourcen danach wieder freigegeben (<math>A=A+C_i</math>).
Können alle benötigten Ressourcen eines Prozesses durch die noch verfügbaren Ressourcen abgedeckt werden (elementweise <math>R_i \le A</math>), so wird dieser Prozess abgearbeitet und seine Ressourcen danach wieder freigegeben (<math>A=A+C_i</math>).
Zeile 51: Zeile 51:
=== Mit Verklemmung ===
=== Mit Verklemmung ===
Ausgangszustand:
Ausgangszustand:
<source>
<pre>
A = [4, 3, 42, 7]
A = [4, 3, 42, 7]
E = [8, 5, 49, 9]
E = [8, 5, 49, 9]
C = [[1, 0, 3, 0], [0, 1, 0, 1], [3, 0, 4, 1], [0, 1, 0, 0]]
C = [[1, 0, 3, 0], [0, 1, 0, 1], [3, 0, 4, 1], [0, 1, 0, 0]]
R = [[0, 4, 0, 0], [3, 0, 2, 1], [0, 5, 36, 3], [0, 0, 0, 9]]
R = [[0, 4, 0, 0], [3, 0, 2, 1], [0, 5, 36, 3], [0, 0, 0, 9]]
</source>
</pre>


Zwischenstände zur Laufzeit, nachdem jeweils Prozess <math>i</math> ausgewählt wurde und terminiert ist:
Zwischenstände zur Laufzeit, nachdem jeweils Prozess <math>i</math> ausgewählt wurde und terminiert ist:
<source>
<pre>
i A
i A
[4, 3, 42, 7]
[4, 3, 42, 7]
1 [4, 4, 42, 8]
1 [4, 4, 42, 8]
0 [5, 4, 45, 8]
0 [5, 4, 45, 8]
</source>
</pre>
'''Verklemmung''', da keine der übrigen Anforderungen (<tt>[0, 5, 36, 3], [0, 0, 0, 9]</tt>) mehr durch verfügbare Ressourcen (<tt>[5, 4, 45, 8]</tt>) abgedeckt werden können.
'''Verklemmung''', da keine der übrigen Anforderungen (<tt>[0, 5, 36, 3], [0, 0, 0, 9]</tt>) mehr durch verfügbare Ressourcen (<tt>[5, 4, 45, 8]</tt>) abgedeckt werden können.
Der Zustand des Systems wird als ''unsicher'' bezeichnet.
Der Zustand des Systems wird als ''unsicher'' bezeichnet.
Zeile 70: Zeile 70:
=== Ohne Verklemmung ===
=== Ohne Verklemmung ===
Ausgangszustand:
Ausgangszustand:
<source>
<pre>
E = [6, 3, 4, 2]
E = [6, 3, 4, 2]
A = [1, 0, 2, 0]
A = [1, 0, 2, 0]
C = [[3, 0, 1, 1], [0, 1, 0, 0], [1, 1, 1, 0], [1, 1, 0, 1], [0, 0, 0, 0]]
C = [[3, 0, 1, 1], [0, 1, 0, 0], [1, 1, 1, 0], [1, 1, 0, 1], [0, 0, 0, 0]]
R = [[1, 1, 0, 0], [0, 1, 1, 2], [3, 1, 0, 0], [0, 0, 1, 0], [2, 1, 1, 0]]
R = [[1, 1, 0, 0], [0, 1, 1, 2], [3, 1, 0, 0], [0, 0, 1, 0], [2, 1, 1, 0]]
</source>
</pre>


Zwischenstände zur Laufzeit, nachdem jeweils Prozess <math>i</math> ausgewählt wurde und terminiert ist:
Zwischenstände zur Laufzeit, nachdem jeweils Prozess <math>i</math> ausgewählt wurde und terminiert ist:
<source>
<pre>
i A
i A
[1, 0, 2, 0]
[1, 0, 2, 0]
Zeile 86: Zeile 86:
1 [5, 2, 3, 2]
1 [5, 2, 3, 2]
2 [6, 3, 4, 2]
2 [6, 3, 4, 2]
</source>
</pre>
'''Erfolg''', alle Prozesse können erfolgreich in der gefundenen Reihenfolge <math>(3,4,0,1,2)</math> ausgeführt werden.
'''Erfolg''', alle Prozesse können erfolgreich in der gefundenen Reihenfolge <math>(3,4,0,1,2)</math> ausgeführt werden.
Der Zustand des Systems wird als ''sicher'' bezeichnet<ref>{{Literatur | Autor = [[Andrew S. Tanenbaum]] | Titel = Modern Operating Systems, 4th Edition | Jahr = 2015 | Verlag = Pearson | Kapitel = 6.5.4 | Seiten = 454-455 | ISBN = 0-13-359162-X}}</ref>.
Der Zustand des Systems wird als ''sicher'' bezeichnet<ref>{{Literatur | Autor = [[Andrew S. Tanenbaum]] | Titel = Modern Operating Systems, 4th Edition | Jahr = 2015 | Verlag = Pearson | Kapitel = 6.5.4 | Seiten = 454–455 | ISBN = 0-13-359162-X}}</ref>.


== Einzelnachweise ==
== Einzelnachweise ==

Version vom 27. März 2016, 09:07 Uhr

Der Bankieralgorithmus (englisch Banker's algorithm) geht auf Edsger W. Dijkstra (1965) zurück und wird zur Vermeidung von Verklemmungen (deadlock) genutzt. Dazu werden die verfügbaren Ressourcen und die Prozesse aufgelistet. Die Ressourcen gliedern sich in gesamte Ressourcen und verfügbare Ressourcen. Die Prozesse erhalten ebenfalls zwei Eigenschaften: Zum einen die Ressourcen, die bereits besetzt werden, zum anderen die noch benötigten Ressourcen.

Dann werden alle Prozesse – sofern die Ausführung möglich ist – nacheinander abgearbeitet und die belegten den verfügbaren Ressourcen zugeführt. Nach Ausführung des Algorithmus steht fest, ob eine Verklemmung vermeidbar ist oder nicht. Kommt der Bankieralgorithmus zu einem erfolgreichen Ende, kann unter Umständen durch unbedachte Ausführungsreihenfolge der Prozesse trotzdem eine Verklemmung entstehen.

Namensursprung

Wie einem Bankier nur eine begrenzte Menge Geld zur Verfügung steht, um die Wünsche seiner Kunden zu befriedigen, so steht einem Betriebssystem nur eine begrenzte Anzahl von Betriebsmitteln zur Verfügung. Der Bankier hält deswegen immer so viel Geld in seinem Tresor zurück, dass er noch von mindestens einem Kunden das komplette Kreditlimit erfüllen kann. Dieser eine Kunde (Prozess) kann dann sein Geschäft erfolgreich zum Abschluss bringen und das verwendete Geld wieder zurück auf die Bank bringen. Nun kann es ein anderer Kunde haben.

Anwendung

Auch wenn der Bankieralgorithmus im Kontext von Betriebssystemen immer als elegante Lösung zur Vermeidung von Verklemmungen aufgeführt ist, sollte bedacht werden, dass dieser in der Praxis kaum Anwendung findet. Der Algorithmus berücksichtigt zum Beispiel nicht, dass die Anzahl von Prozessen sowie Ressourcen variabel ist. Des Weiteren geht der Algorithmus davon aus, dass alle zur Laufzeit von den Prozessen benötigten Ressourcen schon vorher genau bekannt sind, was in Realität nur selten der Fall ist.

Voraussetzungen

Für die Ausführung des Algorithmus müssen folgende Informationen gegeben sein:

  • , die Anzahl verschiedener Ressourcen.
  • , die Anzahl beteiligter Prozesse.
  • , die Menge der insgesamt existierenden (existing) Ressourcen.
  • , die Menge der noch verfügbaren (available) Ressourcen.
  • , die Menge aktuell (currently) vergebener Ressourcen an Prozess .
  • , die Menge der von Prozess noch benötigten (required) Ressourcen.

Findet der Algorithmus eine Reihenfolge, in welcher die Prozesse nacheinander ohne Verklemmung abgearbeitet werden können, befindet sich das System in einem sicheren Zustand.

Implementierung

Folgende Python Funktion implementiert den Bankieralgorithmus: In einer Liste werden alle terminierten Prozesse gesammelt. Solange diese Liste noch nicht alle Prozesse enthält und keine Verklemmung aufgetreten ist werden die Anforderungen aller noch nicht bearbeiteten Prozesse untersucht. Können alle benötigten Ressourcen eines Prozesses durch die noch verfügbaren Ressourcen abgedeckt werden (elementweise ), so wird dieser Prozess abgearbeitet und seine Ressourcen danach wieder freigegeben (). Die Reihenfolge, in welcher die Prozesse dabei bearbeitet werden spielt keine Rolle, da nur anwächst oder unverändert bleibt.

def bankersAlgorithm(E,A,C,R):
    n,m = len(C), len(C[0])
    terminatedProcesses = []
    deadlock = False
    while len(terminatedProcesses) < n and not(deadlock):
        deadlock = True
        for i in range(n):
            if i in terminatedProcesses:
                continue
            elif all([R[i][j] <= A[j] for j in range(m)]):
                # required resources are given to process i
                # process i terminates and gives all his resources back
                A = [C[i][j] + A[j] for j in range(m)]
                terminatedProcesses.append(i)
                deadlock = False
                print i, A
    return not(deadlock), terminatedProcesses

Die Funktion gibt zurück, ob der ermittelte Zustand sicher ist (True/False), sowie die Reihenfolge in welcher die Prozesse ablaufen können.

Beispiele

Mit Verklemmung

Ausgangszustand:

A = [4, 3, 42, 7]
E = [8, 5, 49, 9]
C = [[1, 0, 3, 0], [0, 1, 0, 1], [3, 0, 4, 1], [0, 1, 0, 0]]
R = [[0, 4, 0, 0], [3, 0, 2, 1], [0, 5, 36, 3], [0, 0, 0, 9]]

Zwischenstände zur Laufzeit, nachdem jeweils Prozess ausgewählt wurde und terminiert ist:

i   A
    [4, 3, 42, 7]
1   [4, 4, 42, 8]
0   [5, 4, 45, 8]

Verklemmung, da keine der übrigen Anforderungen ([0, 5, 36, 3], [0, 0, 0, 9]) mehr durch verfügbare Ressourcen ([5, 4, 45, 8]) abgedeckt werden können. Der Zustand des Systems wird als unsicher bezeichnet.

Ohne Verklemmung

Ausgangszustand:

E = [6, 3, 4, 2]
A = [1, 0, 2, 0]
C = [[3, 0, 1, 1], [0, 1, 0, 0], [1, 1, 1, 0], [1, 1, 0, 1], [0, 0, 0, 0]]
R = [[1, 1, 0, 0], [0, 1, 1, 2], [3, 1, 0, 0], [0, 0, 1, 0], [2, 1, 1, 0]]

Zwischenstände zur Laufzeit, nachdem jeweils Prozess ausgewählt wurde und terminiert ist:

i   A
    [1, 0, 2, 0]
3   [2, 1, 2, 1]
4   [2, 1, 2, 1]
0   [5, 1, 3, 2]
1   [5, 2, 3, 2]
2   [6, 3, 4, 2]

Erfolg, alle Prozesse können erfolgreich in der gefundenen Reihenfolge ausgeführt werden. Der Zustand des Systems wird als sicher bezeichnet[1].

Einzelnachweise

  1. Andrew S. Tanenbaum: Modern Operating Systems, 4th Edition. Pearson, 2015, ISBN 0-13-359162-X, 6.5.4, S. 454–455.