Junior
Čo je deadlock?
sobes.tech AI
Odpoveď od AI
Deadlock je situácia slepého miesta v viacvláknovom programovaní, keď dve alebo viac vlákien blokujú navzájom, čakajúc na zdroje, ktoré sú obsadené inými vláknami v rovnakej skupine.
Podmienky vzniku deadlocku (Koffmanove podmienky):
- Vzájomné vylúčenie (Mutual Exclusion): Zdroje nemôžu byť používané súčasne viacerými vláknami.
- Držanie a čakanie (Hold and Wait): Vlákna, ktoré už majú jeden zdroj, čakajú na získanie ďalšieho zdroja, ktorý je obsadený iným vláknom.
- Žiadne predbehnutie (No Preemption): Zdroj nemôže byť vynútene odobraný vláknu, ktoré ho vlastní; môže byť uvoľnený iba samotným vláknom.
- Kruhové čakanie (Circular Wait): Existuje reťazec dvoch alebo viacerých vlákien, kde každé vlákno čaká na zdroj, ktorý vlastní nasledujúce vlákno v reťazci.
Jednoduchý príklad deadlocku:
Dve vlákna, dva zdroje (A a B).
- Vlákno 1 získa zdroj A.
- Vlákno 2 získa zdroj B.
- Vlákno 1 sa pokúsi získať zdroj B (ktorý je obsadený vláknom 2).
- Vlákno 2 sa pokúsi získať zdroj A (ktorý je obsadený vláknom 1).
Obe vlákna sú zablokované navždy.
// Jednoduchý príklad simulácie deadlocku s použitím lock
object resourceA = new object();
object resourceB = new object();
void Thread1Method()
{
lock (resourceA) // Vlákno 1 získalo A
{
Console.WriteLine("Vlákno 1 získalo zdroj A");
Thread.Sleep(100); // Malé zdržanie na demonštráciu možnosti prepínania vlákien
lock (resourceB) // Vlákno 1 sa pokúsi získať B
{
Console.WriteLine("Vlákno 1 získalo zdroj B");
}
}
}
void Thread2Method()
{
lock (resourceB) // Vlákno 2 získalo B
{
Console.WriteLine("Vlákno 2 získalo zdroj B");
Thread.Sleep(100); // Malé zdržanie
lock (resourceA) // Vlákno 2 sa pokúsi získať A
{
Console.WriteLine("Vlákno 2 získalo zdroj A");
}
}
}
// Vytvorenie a spustenie vlákien môže viesť k deadlocku.
// new Thread(Thread1Method).Start();
// new Thread(Thread2Method).Start();
// Spustenie tohto kódu môže, ale nie je nutné, demonštrovať deadlock,
// pretože poradie vykonávania závisí od plánovača.
// Ak vlákno 1 získa A a vlákno 2 získa B skôr, než prvé
// stihne získať B, vznikne deadlock.
Prevencia deadlockov sa často dosahuje:
- Usporiadaním získavania zdrojov (vždy získať zdroje v rovnakom poradí).
- Použitím metód získavania s časovým limitom (pokusit sa získať zdroj v určenom čase).
- Navrhnutím bez potreby držať viac zámkov súčasne.
- Použitím atomárnych operácií alebo vyšších úrovní primitivov na synchronizáciu (napr.
Monitor.TryEnter,ReaderWriterLockSlim).
Deadlocky sú ťažko odhaľovateľné, pretože závisia od poradia vykonávania vlákien a často sa prejavujú iba pri zaťažení. Visual Studio poskytuje nástroje na ich detekciu a analýzu.