Frage

Beim Schreiben von Multithread-Anwendungen sind Deadlocks eines der häufigsten Probleme.

Meine Fragen an die Community sind:

  1. Was ist ein Deadlock?

  2. Wie erkennt man sie?

  3. Kümmern Sie sich um sie?

  4. Und schließlich: Wie verhindern Sie, dass sie auftreten?

War es hilfreich?

Lösung

A sperren tritt auf, wenn mehrere Prozesse gleichzeitig versuchen, auf dieselbe Ressource zuzugreifen.

Ein Prozess geht verloren und muss warten, bis der andere abgeschlossen ist.

A Sackgasse tritt auf, wenn der wartende Prozess noch eine andere Ressource festhält, die der erste benötigt, bevor er abgeschlossen werden kann.

Also ein Beispiel:

Ressource A und Ressource B werden von Prozess X und Prozess Y verwendet

  • X beginnt, A zu verwenden.
  • X und Y versuchen, B zu verwenden
  • Y „gewinnt“ und bekommt zuerst B
  • Jetzt muss Y A verwenden
  • A ist von X gesperrt, das auf Y wartet

Der beste Weg, Deadlocks zu vermeiden, besteht darin, zu vermeiden, dass sich Prozesse auf diese Weise überschneiden.Reduzieren Sie die Notwendigkeit, etwas zu sperren, so weit wie möglich.

Vermeiden Sie in Datenbanken, viele Änderungen an verschiedenen Tabellen in einer einzigen Transaktion vorzunehmen, vermeiden Sie Trigger und wechseln Sie so oft wie möglich zu optimistischen/dirty/nolock-Lesevorgängen.

Andere Tipps

Lassen Sie mich ein reales (nicht wirklich reales) Beispiel für eine Pattsituation aus Kriminalfilmen erläutern.Stellen Sie sich vor, ein Krimineller hält eine Geisel und im Gegensatz dazu hält ein Polizist auch einen Freund des Kriminellen als Geisel.In diesem Fall wird der Kriminelle die Geisel nicht freilassen, wenn der Polizist seinen Freund nicht freilässt.Außerdem wird der Polizist den Freund des Verbrechers nicht freilassen, es sei denn, der Verbrecher lässt die Geisel frei.Dies ist eine endlose, unglaubwürdige Situation, da beide Seiten darauf beharren, den ersten Schritt voneinander zu machen.

Kriminelle und Polizistenszene

enter image description here

Wenn also zwei Threads zwei unterschiedliche Ressourcen benötigen und jeder von ihnen die Sperre der Ressource hat, die der andere benötigt, handelt es sich einfach um einen Deadlock.

Eine weitere allgemeine Erklärung des Deadlocks:Gebrochene Herzen

Du gehst mit einem Mädchen aus und einen Tag nach einem Streit sind beide Seiten untröstlich und warten auf einen Streit Es tut mir leid und ich habe dich vermisst Anruf.In dieser Situation wollen beide Seiten genau dann miteinander kommunizieren, wenn einer von ihnen eine erhält Es tut mir leid Anruf vom anderen.Da keiner von beiden in einem passiven Zustand mit der Kommunikation beginnt und wartet, warten beide darauf, dass der andere mit der Kommunikation beginnt, was zu einer Deadlock-Situation führt.

Deadlocks treten nur dann auf, wenn Sie über zwei oder mehr Sperren verfügen, die gleichzeitig erworben werden können und diese in unterschiedlicher Reihenfolge erfasst werden.

Möglichkeiten, Deadlocks zu vermeiden, sind:

  • Vermeiden Sie Schlösser (wenn möglich),
  • Vermeiden Sie mehr als ein Schloss
  • Nehmen Sie die Schlösser immer in der gleichen Reihenfolge.

Um einen Deadlock zu definieren, würde ich zuerst den Prozess definieren.

Verfahren : Wie wir wissen, ist der Prozess nichts anderes als ein program in der Ausführung.

Ressource : Um einen Programmprozess auszuführen, sind einige Ressourcen erforderlich.Zu den Ressourcenkategorien können Speicher, Drucker, CPUs, geöffnete Dateien, Bandlaufwerke, CD-ROMs usw. gehören.

Sackgasse : Deadlock ist eine Situation oder ein Zustand, in dem zwei oder mehr Prozesse einige Ressourcen halten und versuchen, weitere Ressourcen abzurufen, und sie die Ressourcen nicht freigeben können, bis sie ihre Ausführung abgeschlossen haben.

Deadlock-Zustand oder -Situation

enter image description here

Im obigen Diagramm gibt es zwei Prozesse P1 Und p2 und es gibt zwei Ressourcen R1 Und R2.

Ressource R1 ist dem Prozess zugeordnet P1 und Ressource R2 ist dem Prozess zugeordnet p2.Um die Ausführung des Prozesses abzuschließen P1 braucht Ressourcen R2, Also P1 Anfrage für R2, Aber R2 ist bereits zugeordnet P2.

Auf die gleiche Weise verfahren P2 um seine Ausführungsanforderungen zu erfüllen R1, Aber R1 ist bereits zugeordnet P1.

Beide Prozesse können ihre Ressourcen erst dann freigeben, wenn sie ihre Ausführung abgeschlossen haben.Beide warten also auf eine weitere Ressource und werden ewig warten.Das ist also ein SACKGASSE Zustand.

Damit ein Deadlock auftritt, müssen vier Bedingungen erfüllt sein.

  1. Gegenseitiger Ausschluss - Jede Ressource ist entweder aktuell genau einem Prozess zugeordnet oder sie ist verfügbar.(Zwei Prozesse können nicht gleichzeitig dieselbe Ressource steuern oder in ihrem kritischen Abschnitt befinden).
  2. Halten und warten - Prozesse, die derzeit Ressourcen halten, können neue Ressourcen anfordern.
  3. Kein Vorkaufsrecht - Sobald ein Prozess eine Ressource enthält, kann sie nicht von einem anderen Prozess oder dem Kernel weggenommen werden.
  4. Zirkuläres Warten – Jeder Prozess wartet darauf, eine Ressource zu erhalten, die von einem anderen Prozess gehalten wird.

und alle diese Bedingungen sind im obigen Diagramm erfüllt.

Ein Deadlock tritt auf, wenn ein Thread auf etwas wartet, das nie eintritt.

Dies geschieht normalerweise, wenn ein Thread auf einen Mutex oder eine Semaphore wartet, die vom Vorbesitzer nie freigegeben wurde.

Es kommt auch häufig vor, wenn Sie eine Situation mit zwei Threads und zwei Sperren wie dieser haben:

Thread 1               Thread 2

Lock1->Lock();         Lock2->Lock();
WaitForLock2();        WaitForLock1();   <-- Oops!

Sie erkennen sie im Allgemeinen, weil Dinge, die Sie erwarten, nie eintreten oder die Anwendung vollständig hängen bleibt.

Sie können sich das ansehen wunderbare Artikel, unter Abschnitt Sackgasse.Es ist in C#, aber die Idee ist für andere Plattformen immer noch dieselbe.Zur leichteren Lektüre zitiere ich hier

Ein Deadlock findet statt, wenn zwei Themen jeweils auf eine voneinander gehaltene Ressource warten, sodass keiner weitergehen kann.Der einfachste Weg, dies zu veranschaulichen, ist mit zwei Schlössern:

object locker1 = new object();
object locker2 = new object();

new Thread (() => {
                    lock (locker1)
                    {
                      Thread.Sleep (1000);
                      lock (locker2);      // Deadlock
                    }
                  }).Start();
lock (locker2)
{
  Thread.Sleep (1000);
  lock (locker1);                          // Deadlock
}

Deadlock ist ein häufiges Problem bei Multiprocessing-/Multiprogramming-Problemen im Betriebssystem.Angenommen, es gibt zwei Prozesse P1, P2 und zwei global gemeinsam nutzbare Ressourcen R1, R2 und im kritischen Abschnitt muss auf beide Ressourcen zugegriffen werden

Zunächst weist das Betriebssystem R1 dem Prozess P1 und R2 dem Prozess P2 zu.Da beide Prozesse gleichzeitig ausgeführt werden, beginnen sie möglicherweise mit der Ausführung ihres Codes, das PROBLEM tritt jedoch auf, wenn ein Prozess den kritischen Abschnitt erreicht.Prozess R1 wartet also darauf, dass Prozess P2 R2 freigibt und umgekehrt ...Sie werden also ewig warten (DEADLOCK-BEDINGUNG).

Eine kleine ANALOGIE...

Deine Mutter(OS),
Du(P1),
Dein Bruder (P2),
Apfel(R1),
Messer(R2),
kritischer Abschnitt (Apfel mit Messer schneiden).

Deine Mutter gibt dir am Anfang den Apfel und das Messer für deinen Bruder.
Beide sind glücklich und spielen (führen ihre Codes aus).
Jeder von euch möchte irgendwann den Apfel (kritischer Abschnitt) anschneiden.
Du willst deinem Bruder den Apfel nicht geben.
Dein Bruder will dir das Messer nicht geben.
Ihr werdet also noch sehr lange warten :)

Ein Deadlock tritt auf, wenn es eine kreisförmige Kette von Threads oder Prozessen gibt, die jeweils eine gesperrte Ressource enthalten und versuchen, eine Ressource zu sperren, die vom nächsten Element in der Kette gehalten wird.Zum Beispiel zwei Threads, die Sperre A bzw. Sperre B halten und beide versuchen, die andere Sperre zu erhalten.

Ein Deadlock tritt auf, wenn zwei Threads Sperren erwerben, die verhindern, dass einer von ihnen fortschreitet.Der beste Weg, sie zu vermeiden, ist eine sorgfältige Entwicklung.Viele eingebettete Systeme schützen sich davor, indem sie einen Watchdog-Timer verwenden (ein Timer, der das System immer dann zurücksetzt, wenn es für eine bestimmte Zeitspanne hängen bleibt).

Ein Deadlock ist ein Zustand eines Systems, in dem kein einzelner Prozess/Thread in der Lage ist, eine Aktion auszuführen.Wie von anderen erwähnt, ist ein Deadlock typischerweise das Ergebnis einer Situation, in der jeder Prozess/Thread eine Sperre für eine Ressource erhalten möchte, die bereits von einem anderen (oder sogar demselben) Prozess/Thread gesperrt ist.

Es gibt verschiedene Methoden, sie zu finden und zu vermeiden.Man denkt sehr intensiv nach und/oder probiert viele Dinge aus.Der Umgang mit Parallelität ist jedoch bekanntermaßen schwierig und die meisten (wenn nicht alle) Menschen werden Probleme nicht vollständig vermeiden können.

Einige formellere Methoden können nützlich sein, wenn Sie sich ernsthaft mit solchen Problemen befassen möchten.Die praktischste Methode, die mir bekannt ist, ist die Verwendung des prozesstheoretischen Ansatzes.Hier modellieren Sie Ihr System in einer Prozesssprache (z. B.CCS, CSP, ACP, mCRL2, LOTOS) und verwenden Sie die verfügbaren Tools zur (Modell-)Prüfung auf Deadlocks (und möglicherweise auch einige andere Eigenschaften).Beispiele für zu verwendende Toolsets sind FDR, mCRL2, CADP und Uppaal.Einige mutige Seelen könnten sogar beweisen, dass ihre Systeme frei von Blockaden sind, indem sie rein symbolische Methoden anwenden (Theorembeweis;suchen Sie nach Owicki-Gries).

Allerdings erfordern diese formalen Methoden typischerweise einen gewissen Aufwand (z. B.Erlernen der Grundlagen der Prozesstheorie).Aber ich denke, das ist einfach eine Folge der Tatsache, dass diese Probleme schwierig sind.

Ein Deadlock ist eine Situation, in der weniger Ressourcen verfügbar sind, als von einem anderen Prozess angefordert wird.Dies bedeutet, dass, wenn die Anzahl der verfügbaren Ressourcen geringer wird als vom Benutzer angefordert, der Prozess zu diesem Zeitpunkt in den Wartezustand wechselt. Manchmal nimmt die Wartezeit zu und es besteht dann keine Möglichkeit, das Problem des Ressourcenmangels zu überprüfen Diese Situation wird als Deadlock bezeichnet.Tatsächlich ist Deadlock ein großes Problem für uns und tritt nur in Multitasking-Betriebssystemen auf. Deadlock kann nicht in Single-Tasking-Betriebssystemen auftreten, da alle Ressourcen nur für die gerade ausgeführte Aufgabe vorhanden sind.

Oben sind einige Erklärungen nett.Ich hoffe, das könnte auch nützlich sein:https://ora-data.blogspot.in/2017/04/deadlock-in-oracle.html

Wenn in einer Datenbank eine Sitzung (z. B.ora) möchte eine Ressource, die von einer anderen Sitzung (z. B.Daten), aber diese Sitzung (Daten) benötigt auch eine Ressource, die von der ersten Sitzung (ora) gehalten wird.Es können auch mehr als zwei Sitzungen durchgeführt werden, die Idee bleibt jedoch dieselbe.Tatsächlich verhindern Deadlocks, dass einige Transaktionen weiterhin funktionieren.Zum Beispiel:Angenommen, Ora-Data hält Sperre A und fordert die Sperre B und SKU auf Sperre B und Anfragen von Lock A.

Danke,

Ein Deadlock tritt auf, wenn ein Thread auf den Abschluss eines anderen Threads wartet und umgekehrt.

Wie vermeiden?
- Vermeiden Sie verschachtelte Sperren
- Vermeiden Sie unnötige Sperren
- Thread-Join() verwenden

Wie erkennen Sie es?
Führen Sie diesen Befehl in cmd aus:

jcmd $PID Thread.print

Referenz :geeksforgeeks

Ein klassisches und sehr einfaches Programm zum Verstehen Sackgasse Situation :-

public class Lazy {

    private static boolean initialized = false;

    static {
        Thread t = new Thread(new Runnable() {
            public void run() {
                initialized = true;
            }
        });

        t.start();

        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println(initialized);
    }
}

Wenn der Haupt -Thread faul aufruft.Der Haupt -Thread setzt nun auf False initialisiert, erstellt und startet einen Hintergrund -Thread, dessen Run -Methode auf True initialisiert wird, und wartet auf die Fertigstellung des Hintergrund -Threads.

Diesmal wird die Klasse gerade von einem anderen Thread initialisiert.Unter diesen Umständen wartet der aktuelle Thread, der der Hintergrund -Thread ist, auf das Klassenobjekt, bis die Initialisierung abgeschlossen ist.Leider wartet der Thread, der die Initialisierung, der Haupt -Thread, auf die Fertigstellung des Hintergrund -Threads wartet.Da die beiden Themen jetzt aufeinander warten, ist das Programm Festgefahren.

Das Deadlock-Problem

  • Die frühesten Computerbetriebssysteme haben jeweils nur ein Programm ausgeführt
  • Alle Ressourcen des Systems standen diesem einen Programm zur Verfügung
  • Später führten Betriebssysteme mehrere Programme gleichzeitig durch, um sie zu verschieben
  • Die Programme mussten im Voraus festlegen, welche Ressourcen sie benötigten, damit sie Konflikte mit anderen Programmen vermeiden konnten, die gleichzeitig ausgeführt werden
  • Schließlich boten einige Betriebssysteme eine dynamische Zuweisung von Ressourcen an
  • Programme könnten weitere Ressourcenzuweisungen anfordern, nachdem sie begonnen hatten
  • Dies führte zum Problem des Deadlocks

Eine Reihe blockierter Prozesse, die jeweils eine Ressource halten und darauf warten, eine Ressource zu erwerben, die von einem anderen Prozess im Set gehalten wird

Eine Situation, in der 02 oder mehr konkurrierende Aktionen auf das Ende des anderen warten, und somit es auch nicht tut

Deadlock-Charakterisierung

  • Gegenseitiger Ausschluss
  • Halten und warten
  • Kein Vorkaufsrecht
  • Zirkuläres Warten

Methoden zum Umgang mit Deadlocks

  • Stellen Sie sicher, dass das System niemals in einen Deadlock-Zustand gerät
  • Lassen Sie das System einen Deadlock -Zustand betreten und sich dann erholen
  • Ignorieren Sie das Problem und tun Sie vor, dass Deadlocks im System niemals auftreten.Wird von den meisten Betriebssystemen verwendet, einschließlich Unix

Deadlock-Prävention

  • Gegenseitiger Ausschluss – nicht erforderlich für gemeinsam nutzbare Ressourcen;muss für nicht gemeinsam nutzbare Ressourcen gelten

  • Halten und warten - muss garantieren, dass ein Prozess, wenn er eine Ressource anfordert, keine anderen Ressourcen enthält

  • Kein Vorkaufsrecht - Wenn ein Prozess, der einige Ressourcen enthält

  • Zirkuläres Warten - Erzwingen Sie eine Gesamtreihenfolge aller Ressourcentypen und verlangen, dass jeder Prozess Ressourcen in einer zunehmenden Aufzählung anfordert

Mutex ist im Wesentlichen eine Sperre, die einen geschützten Zugriff auf gemeinsam genutzte Ressourcen ermöglicht.Unter Linux ist der Thread-Mutex-Datentyp pthread_mutex_t.Initialisieren Sie es vor der Verwendung.

Um auf gemeinsam genutzte Ressourcen zuzugreifen, müssen Sie den Mutex sperren.Wenn der Mutex bereits gesperrt ist, blockiert der Aufruf den Thread, bis der Mutex entsperrt wird.Nach Abschluss des Besuchs gemeinsam genutzter Ressourcen müssen Sie diese freischalten.

Insgesamt gibt es ein paar ungeschriebene Grundprinzipien:

  • Besorgen Sie sich die Sperre, bevor Sie die gemeinsam genutzten Ressourcen verwenden.

  • Halten Sie die Sperre so kurz wie möglich.

  • Geben Sie die Sperre frei, wenn der Thread einen Fehler zurückgibt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top