Junior
Mi az a deadlock?
sobes.tech MI
Válasz az MI-től
Deadlock — ez egy holtponti helyzet több szálas programozásban, amikor két vagy több szál blokkolja egymást, várva az erőforrásokra, amelyeket más szálak foglalnak ebben a csoportban.
A deadlock kialakulásának feltételei (Koffman-féle feltételek):
- Kölcsönös kizárás (Mutual Exclusion): Az erőforrásokat nem lehet egyszerre több szállal használni.
- Tartás és várakozás (Hold and Wait): Azok a szálak, amelyek már rendelkeznek egy erőforrással, várnak egy további erőforrásra, amit egy másik szál foglal.
- Visszavonás hiánya (No Preemption): Az erőforrást nem lehet kényszeríteni egy szálból elvenni; csak a szál szabadon engedheti.
- Körkörös várakozás (Circular Wait): Két vagy több szál láncolata, ahol minden szál egy olyan erőforrást vár, amit a következő szál foglal.
Egyszerű példa deadlockra:
Két szál, két erőforrás (A és B).
- Az 1. szál lefoglalja az A-t.
- A 2. szál lefoglalja a B-t.
- Az 1. szál megpróbálja lefoglalni a B-t (amelyet a 2. szál foglal).
- A 2. szál megpróbálja lefoglalni az A-t (amelyet az 1. szál foglal).
Mindkét szál örökre blokkolva van.
// Egyszerű deadlock szimuláció lock használatával
object resourceA = new object();
object resourceB = new object();
void Thread1Method()
{
lock (resourceA) // Az 1. szál lefoglalja az A-t
{
Console.WriteLine("Szál 1 lefoglalta az erőforrás A");
Thread.Sleep(100); // Kis késleltetés a szálváltás demonstrálására
lock (resourceB) // Az 1. szál megpróbálja lefoglalni a B-t
{
Console.WriteLine("Szál 1 lefoglalta az erőforrás B");
}
}
}
void Thread2Method()
{
lock (resourceB) // A 2. szál lefoglalja a B-t
{
Console.WriteLine("Szál 2 lefoglalta az erőforrás B");
Thread.Sleep(100); // Kis késleltetés
lock (resourceA) // A 2. szál megpróbálja lefoglalni az A-t
{
Console.WriteLine("Szál 2 lefoglalta az erőforrás A");
}
}
}
// Szálak létrehozása és indítása deadlock-hoz vezethet.
// new Thread(Thread1Method).Start();
// new Thread(Thread2Method).Start();
// Ez a kód futtatásával előfordulhat, de nem feltétlenül, deadlock-ot mutatva,
// mivel a végrehajtási sorrend a ütemezőtől függ.
// Ha az 1. szál lefoglalja az A-t, és a 2. szál lefoglalja a B-t, mielőtt az első
// szál lefoglalná a B-t, deadlock alakul ki.
A deadlockok megelőzése gyakran a következőkkel érhető el:
- Erőforrások foglalási sorrendjének egységesítése (mindig ugyanabban a sorrendben foglalni az erőforrásokat).
- Időkorlátos foglalási módszerek alkalmazása (próbálja meg foglalni az erőforrást adott időn belül).
- Olyan tervezés, amely nem igényli több zárolás egyidejű fenntartását.
- Atom műveletek vagy magasabb szintű szinkronizációs primitívek használata (pl.
Monitor.TryEnter,ReaderWriterLockSlim).
A deadlockokat nehéz hibakeresni, mivel a szálak végrehajtási sorrendjétől függenek, és gyakran csak terhelés alatt jelentkeznek. A Visual Studio eszközöket kínál ezek felismerésére és elemzésére.