Was ist ein Deadlock?


Antworten:


206

Eine Sperre tritt auf, wenn mehrere Prozesse gleichzeitig versuchen, auf dieselbe Ressource zuzugreifen.

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

Ein Deadlock tritt auf, wenn der Wartevorgang noch an einer anderen Ressource festhält, die der erste benötigt, bevor er beendet werden kann.

Ein Beispiel:

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

  • X beginnt mit der Verwendung von A.
  • X und Y versuchen, B zu verwenden
  • Y 'gewinnt' und bekommt zuerst B.
  • Jetzt muss Y A verwenden
  • A wird von X gesperrt, das auf Y wartet

Der beste Weg, um Deadlocks zu vermeiden, besteht darin, zu vermeiden, dass Prozesse auf diese Weise gekreuzt werden. Reduzieren Sie die Notwendigkeit, alles so weit wie möglich zu sperren.

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


9
Ich verwende den Prozess hier als Verallgemeinerung, nicht speziell als Betriebssystemprozess. Dies können Threads sein, aber auch völlig andere Anwendungen oder Datenbankverbindungen. Das Muster ist das gleiche.
Keith

1
Hallo, angesichts dieses Szenarios: Thread A sperrt Ressource A und hat einen langen Prozess. Thread B wartet darauf, Ressource A zu sperren. CPU-Zeitauslastung: 20%. Können Sie dies als Deadlock-Situation betrachten?
RickyProgrammer

2
@rickyProgrammer nein, das ist nur eine normale Wartezeit, obwohl der Unterschied ein wenig akademisch ist. B Warten auf langsam A ist eine Sperre, B Warten auf A Warten auf B ist eine Sackgasse.
Keith

Deadlock ist also mehr von zwei Prozessen mit gesperrten Ressourcen, die darauf warten, dass diese Ressourcen freigegeben werden.
RickyProgrammer

2
@rickyProgrammer Es ist eine Sperre, die aufgrund der kreisförmigen Warteschlange nicht frei wird, egal wie lange Sie warten.
Keith

126

Lassen Sie mich ein reales (nicht wirklich reales) Beispiel für eine Deadlock-Situation aus den Kriminalfilmen erklären. Stellen Sie sich vor, ein Verbrecher hält eine Geisel und dagegen hält ein Polizist auch eine Geisel, die ein Freund des Verbrechers ist. In diesem Fall wird der Verbrecher die Geisel nicht gehen lassen, wenn der Polizist seinen Freund nicht gehen lässt. Auch der Polizist wird den Freund des Verbrechers nicht loslassen, es sei denn, der Verbrecher lässt die Geisel frei. Dies ist eine endlose, nicht vertrauenswürdige Situation, da beide Seiten auf dem ersten Schritt voneinander bestehen.

Kriminelle & Polizisten-Szene

Geben Sie hier die Bildbeschreibung ein

Wenn also zwei Threads zwei verschiedene Ressourcen benötigen und jeder von ihnen die Sperre der Ressource hat, die der andere benötigt, ist dies ein Deadlock.

Eine weitere hochrangige Erklärung für Deadlock: Broken Hearts

Sie sind mit einem Mädchen zusammen und einen Tag nach einem Streit sind beide Seiten gebrochen und warten auf einen Anruf, bei dem es mir leid tut und ich Sie verpasst habe . In dieser Situation wollen beide Seiten miteinander kommunizieren , wenn und nur wenn einer von ihnen eine empfängt I-am-Entschuldigung Anruf von der anderen Seite . Da keiner von beiden die Kommunikation starten und in einem passiven Zustand warten wird, warten beide darauf, dass der andere die Kommunikation startet, was zu einer Deadlock-Situation führt.


Sollten die Threads nicht zu verschiedenen Prozessen gehören? Können Threads, die zum selben Prozess gehören, auch einen Deadlock verursachen?
Lords

1
@diabolicfreak Es spielt keine Rolle, ob die Threads zum selben Prozess gehören oder nicht.
Sam Malayek

2
Ein weiteres Beispiel aus dem wirklichen Leben könnten vier Autos sein, die gleichzeitig zwei gleiche Straßen in vier Richtungen überqueren. Jeder muss einem Auto von rechts Platz machen, damit niemand weitermachen kann.
LoBo

35

Deadlocks treten nur auf, wenn Sie zwei oder mehr Sperren haben, die gleichzeitig erworben werden können und in unterschiedlicher Reihenfolge erfasst werden.

Möglichkeiten zur Vermeidung von Deadlocks sind:

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

Der dritte Punkt, um einen Deadlock zu verhindern (nehmen Sie die Sperren immer in der gleichen Reihenfolge), ist von entscheidender Bedeutung, was in der Codierungspraxis leicht zu vergessen ist.
Qiang Xu

20

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

Prozess : Wie wir wissen, ist der Prozess nichts anderes als eine programAusführung.

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

Deadlock : Deadlock ist eine Situation oder Bedingung, in der zwei oder mehr Prozesse einige Ressourcen halten und versuchen, weitere Ressourcen zu erwerben, und sie die Ressourcen erst freigeben können, wenn sie dort ausgeführt werden.

Deadlock-Zustand oder Situation

Geben Sie hier die Bildbeschreibung ein

In dem obigen Diagramm gibt es zwei Prozesse P1 und p2 und es gibt zwei Ressourcen R1 und R2 .

Die Ressource R1 ist dem Prozess P1 und die Ressource R2 dem Prozess p2 zugeordnet . Um die Ausführung des Prozesses P1 abzuschließen , wird also die Ressource R2 benötigt fordert P1 R2 an , aber R2 ist bereits P2 zugeordnet .

Auf die gleiche Weise Prozess P2 , um seine Ausführung abzuschließen, R1 , aber R1 ist bereits P1 zugeordnet .

Beide Prozesse können ihre Ressource erst freigeben, wenn sie ihre Ausführung abgeschlossen haben. Beide warten also auf weitere Ressourcen und werden für immer warten. Dies ist also eine DEADLOCK- Bedingung.

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

  1. Gegenseitiger Ausschluss - Jede Ressource ist entweder aktuell genau einem Prozess zugeordnet oder verfügbar. (Zwei Prozesse können nicht gleichzeitig dieselbe Ressource steuern oder sich in ihrem kritischen Bereich befinden.)
  2. Halten und warten - Prozesse, die derzeit Ressourcen enthalten, können neue Ressourcen anfordern.
  3. Keine Vorauszahlung - Sobald ein Prozess eine Ressource enthält, kann diese nicht mehr von einem anderen Prozess oder dem Kernel entfernt werden.
  4. Rundschreiben 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.


8

Ein Deadlock tritt auf, wenn ein Thread auf etwas wartet, das niemals auftritt.

In der Regel tritt dies auf, wenn ein Thread auf einen Mutex oder ein Semaphor wartet, das bzw. das vom Vorbesitzer nie freigegeben wurde.

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

Thread 1               Thread 2

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

Sie erkennen sie im Allgemeinen, weil Dinge, von denen Sie erwarten, dass sie niemals passieren, oder die Anwendung vollständig hängt.


Ein Deadlock tritt auf, wenn ein Thread auf etwas wartet, das nicht auftreten kann.
Marquis von Lorne

4

Sie können sich diese wunderbaren Artikel unter Deadlock ansehen . Es ist in C #, aber die Idee ist für andere Plattformen immer noch dieselbe. Ich zitiere hier zum einfachen Lesen

Ein Deadlock tritt auf, wenn jeweils zwei Threads auf eine Ressource warten, die von der anderen gehalten wird, sodass keiner fortfahren kann. Dies lässt sich am einfachsten mit zwei Schlössern veranschaulichen:

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
}

4

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

Zu Beginn weist das Betriebssystem R1 dem Prozess P1 und R2 dem Prozess P2 zu. Da beide Prozesse gleichzeitig ausgeführt werden, können sie mit der Ausführung ihres Codes beginnen. Das PROBLEM tritt jedoch auf, wenn ein Prozess den kritischen Abschnitt erreicht. Der Prozess R1 wartet also darauf, dass der Prozess P2 R2 freigibt, und umgekehrt ... Also warten sie für immer (DEADLOCK-ZUSTAND).

Eine kleine ANALOGIE ...

Deine Mutter (OS),
du (P1),
dein Bruder (P2),
Apple (R1),
Messer (R2),
kritischer Abschnitt (Apfel mit Messer schneiden).

Deine Mutter gibt dir am Anfang den Apfel und das Messer an deinen Bruder.
Beide sind glücklich und spielen (Ausführen ihrer Codes).
Jeder von euch möchte irgendwann den Apfel schneiden (kritischer Abschnitt).
Du willst deinem Bruder den Apfel nicht geben.
Dein Bruder will dir das Messer nicht geben.
Ihr beide werdet also lange, sehr lange warten :)


2

Ein Deadlock tritt auf, wenn zwei Threads Sperren erwerben, die verhindern, dass einer von beiden fortschreitet. Der beste Weg, sie zu vermeiden, ist eine sorgfältige Entwicklung. Viele eingebettete Systeme schützen vor ihnen, indem sie einen Watchdog-Timer verwenden (einen Timer, der das System zurücksetzt, wenn es für einen bestimmten Zeitraum hängt).


2

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 jeweils Sperre A und Sperre B halten und beide versuchen, die andere Sperre zu erlangen.


Ich stimme dir zu. Ihre Antwort ist prägnanter als oben, da sie verwirrende Deadlocks durch Prozesse oder Threads verursachen.
Jemand

1

Ein klassisches und sehr einfaches Programm zum Verständnis der Deadlock- 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 Hauptthread Lazy.main aufruft, prüft er, ob die Klasse Lazy initialisiert wurde, und beginnt mit der Initialisierung der Klasse. Der Hauptthread setzt jetzt initialisiert auf false, erstellt und startet einen Hintergrundthread, dessen Ausführungsmethode auf true initialisiert gesetzt wird, und wartet, bis der Hintergrundthread abgeschlossen ist.

Dieses Mal wird die Klasse derzeit von einem anderen Thread initialisiert. Unter diesen Umständen wartet der aktuelle Thread, bei dem es sich um den Hintergrundthread handelt, auf das Class-Objekt, bis die Initialisierung abgeschlossen ist. Leider wartet der Thread, der die Initialisierung durchführt, der Hauptthread, auf den Abschluss des Hintergrundthreads. Da die beiden Threads jetzt aufeinander warten, ist das Programm DEADLOCKED.


0

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

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

Einige formellere Methoden können hilfreich sein, wenn Sie sich ernsthaft mit solchen Problemen befassen. Die praktischste Methode, die mir bekannt ist, ist die Verwendung des prozess-theoretischen Ansatzes. Hier modellieren Sie Ihr System in einer Prozesssprache (z. B. CCS, CSP, ACP, mCRL2, LOTOS) und verwenden die verfügbaren Tools, um (Modell-) nach Deadlocks (und möglicherweise auch einigen anderen Eigenschaften) zu suchen. Beispiele für zu verwendende Tools sind FDR, mCRL2, CADP und Uppaal. Einige mutige Seelen könnten sogar beweisen, dass ihre Systeme mit rein symbolischen Methoden festgefahren sind (Theorembeweis; Suche nach Owicki-Gries).

Diese formalen Methoden erfordern jedoch in der Regel einige Anstrengungen (z. B. Erlernen der Grundlagen der Prozesstheorie). Aber ich denke, das ist einfach eine Folge der Tatsache, dass diese Probleme schwierig sind.


0

Ein Deadlock ist eine Situation, in der weniger Ressourcen verfügbar sind, als von den verschiedenen Prozessen angefordert wird. Dies bedeutet, dass, wenn die Anzahl der verfügbaren Ressourcen geringer wird als vom Benutzer angefordert, der Prozess zu diesem Zeitpunkt in einen Wartezustand versetzt wird. Manchmal steigt das Warten mehr und es besteht 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 unter Multitasking-Betriebssystemen auf. Deadlock kann unter Single-Tasking-Betriebssystemen nicht auftreten, da alle Ressourcen nur für die Aufgabe vorhanden sind, die gerade ausgeführt wird.


0

Oben sind einige Erklärungen nett. Hoffe das kann auch nützlich sein: https://ora-data.blogspot.in/2017/04/deadlock-in-oracle.html

In einer Datenbank möchte eine Sitzung (z. B. ora), dass eine Ressource von einer anderen Sitzung (z. B. Daten) gehalten wird, diese Sitzung (Daten) jedoch auch eine Ressource, die von der ersten Sitzung (ora) gehalten wird. Es können auch mehr als 2 Sitzungen beteiligt sein, aber die Idee wird dieselbe sein. Tatsächlich verhindern Deadlocks, dass einige Transaktionen weiterhin funktionieren. Beispiel: Angenommen, ORA-DATA hält Sperre A und fordert Sperre B an, und SKU hält Sperre B und fordert Sperre A an.

Vielen Dank,


0

Ein Deadlock tritt auf, wenn ein Thread darauf wartet, dass ein anderer Thread beendet wird und umgekehrt.

Wie vermeide ich?
- Vermeiden Sie verschachtelte Sperren.
- Vermeiden Sie unnötige Sperren.
- Verwenden Sie thread join ()

Wie erkennt man das?
Führen Sie diesen Befehl in cmd aus:

jcmd $PID Thread.print

Referenz : Geeksforgeeks


0

Deadlocks treten nicht nur bei Sperren auf, obwohl dies die häufigste Ursache ist. In C ++ können Sie einen Deadlock mit zwei Threads und ohne Sperren erstellen, indem Sie einfach jeden Thread-Aufruf join () für das std :: thread-Objekt für den anderen festlegen.


0

Sperrenbasierte Parallelitätskontrolle

Die Verwendung der Sperrung zur Steuerung des Zugriffs auf gemeinsam genutzte Ressourcen ist anfällig für Deadlocks, und der Transaktionsplaner allein kann deren Auftreten nicht verhindern.

Beispielsweise verwenden relationale Datenbanksysteme verschiedene Sperren, um die ACID-Eigenschaften von Transaktionen zu gewährleisten .

Unabhängig davon, welches relationale Datenbanksystem Sie verwenden, werden beim Ändern (z. B. UPDATEoder DELETE) eines bestimmten Tabellendatensatzes immer Sperren erworben . Ohne das Sperren einer Zeile, die durch eine aktuell ausgeführte Transaktion geändert wurde, wäre Atomicity gefährdet .

Was ist ein Deadlock?

Wie in diesem Artikel erläutert , tritt ein Deadlock auf, wenn zwei gleichzeitige Transaktionen nicht ausgeführt werden können, da jeder darauf wartet, dass der andere eine Sperre aufhebt, wie in der folgenden Abbildung dargestellt.

Geben Sie hier die Bildbeschreibung ein

Da sich beide Transaktionen in der Sperrenerfassungsphase befinden, gibt keine der beiden eine Sperre frei, bevor die nächste erworben wird.

Wiederherstellung nach einer Deadlock-Situation

Wenn Sie einen Concurrency Control-Algorithmus verwenden, der auf Sperren basiert, besteht immer das Risiko, dass Sie in einer Deadlock-Situation ausgeführt werden. Deadlocks können in jeder Parallelitätsumgebung auftreten, nicht nur in einem Datenbanksystem.

Beispielsweise kann ein Multithreading-Programm einen Deadlock verursachen, wenn zwei oder mehr Threads auf zuvor erfasste Sperren warten, sodass kein Thread Fortschritte erzielen kann. Wenn dies in einer Java-Anwendung geschieht, kann die JVM einen Thread nicht einfach zwingen, seine Ausführung zu stoppen und seine Sperren aufzuheben.

Selbst wenn die ThreadKlasse eine stopMethode verfügbar macht , ist diese Methode seit Java 1.1 veraltet, da sie dazu führen kann, dass Objekte nach dem Stoppen eines Threads in einem inkonsistenten Zustand belassen werden. Stattdessen definiert Java eineinterrupt Methode, die als Hinweis fungiert, da ein unterbrochener Thread die Unterbrechung einfach ignorieren und ihre Ausführung fortsetzen kann.

Aus diesem Grund kann sich eine Java-Anwendung nicht von einer Deadlock-Situation erholen, und es liegt in der Verantwortung des Anwendungsentwicklers, die Anforderungen für die Sperrenerfassung so anzuordnen, dass niemals Deadlocks auftreten können.

Ein Datenbanksystem kann jedoch einen bestimmten Befehl zum Erwerb von Sperren nicht erzwingen, da nicht vorhersehbar ist, welche anderen Sperren eine bestimmte Transaktion weiter erwerben möchte. Das Beibehalten der Sperrreihenfolge liegt in der Verantwortung der Datenzugriffsschicht, und die Datenbank kann nur bei der Wiederherstellung nach einer Deadlock-Situation helfen.

Das Datenbankmodul führt einen separaten Prozess aus, der das aktuelle Konfliktdiagramm nach Wartezyklen durchsucht (die durch Deadlocks verursacht werden). Wenn ein Zyklus erkannt wird, wählt das Datenbankmodul eine Transaktion aus und bricht sie ab, wodurch die Sperren aufgehoben werden, sodass die andere Transaktion Fortschritte erzielen kann.

Im Gegensatz zur JVM ist eine Datenbanktransaktion als atomare Arbeitseinheit konzipiert. Daher verlässt ein Rollback die Datenbank in einem konsistenten Zustand.

Weitere Informationen zu diesem Thema finden Sie auch in diesem Artikel .


-2

Mutex ist im Wesentlichen eine Sperre, die geschützten Zugriff auf gemeinsam genutzte Ressourcen bietet. Unter Linux lautet der Thread-Mutex-Datentyp pthread_mutex_t. Initialisieren Sie es vor dem Gebrauch.

Um auf freigegebene Ressourcen zugreifen zu können, müssen Sie den Mutex sperren. Befindet sich der Mutex bereits in der Sperre, blockiert der Aufruf den Thread, bis der Mutex entsperrt wird. Nach Abschluss des Besuchs freigegebener Ressourcen müssen Sie diese entsperren.

Insgesamt gibt es einige ungeschriebene Grundprinzipien:

  • Beziehen Sie die Sperre, bevor Sie die freigegebenen Ressourcen verwenden.

  • Halten Sie das Schloss so kurz wie möglich.

  • Lösen Sie die Sperre, wenn der Thread einen Fehler zurückgibt.


3
Dies beschreibt eine Sperre, keine Sackgasse.
Marquis von Lorne
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.