Deadlock – zakleszczenie

Jest to sytuacja, w której dwa lub więcej wątków/procesów są zablokowane ponieważ każdy z nich czeka na zakończenie działania drugiego.

W powyższym przykładzie:
  1. W sekundzie zerowej pierwszy proces rozpoczyna operację na zasobie A blokując go na czas wykonania całego bloku (blok oznaczony kolorem niebieskim)
  2. W pierwszej sekundzie drugi proces rozpoczyna operację na zasobie B, tym samym go blokując na czas wykonania całego bloku (blok oznaczony kolorem zielonym).
  3. W drugiej sekundzie drugi proces wciąż wykonuje operację na zasobie B, gdy pierwszy proces skończył już swoją pierwszą operację i próbuje wykonać drugą operację na zasobie B. Niestety zasób B jest tymczasowo zablokowany przez proces drugi – trzeba czekać.
  4. W sekundzie trzeciej drugi proces kończy operację na zasobie B (wciąż go blokując) i próbuje wykonać kolejną operację na zasobie A. Niestety zasób A jest tymczasowo zablokowany przez proces pierwszy- trzeba czekać.
  5. I mamy deadlock – pierwszy proces czeka na drugi, a drugi czeka na pierwszy.

Jak unikać?

  1. Należy skracać na ile tylko się da bloki synchronizowane/transakcje (a jeśli to możliwe to ich unikać).
  2. W przypadku bloków synchronizowanych należy unikać zagnieżdżeń (blok synchronizowany w bloku synchronizowanym).
  3. Jeśli jest to możliwe to warto używać blokad, które próbują nałożyć blokadę tylko przez określony czas, jeśli się nie uda to rezygnują (lock with timeout).

Warto zajrzeć

  1. Przykład w języku Java https://github.com/damianradowiecki/deadlock-example
  2. Opis deadlocku w bazach danych, świetny przykład Vlada Mihalcea https://vladmihalcea.com/database-deadlock/