Junior
Wat is een deadlock?
sobes.tech AI
Antwoord van AI
Deadlock is een uitzichtloze situatie in multithread programming, waarbij twee of meer threads elkaar blokkeren terwijl ze wachten op resources die door andere threads in dezelfde groep worden gebruikt.
Voorwaarden voor het ontstaan van een deadlock (Coffman-voorwaarden):
- Wederzijdse uitsluiting (Mutual Exclusion): Resources kunnen niet gelijktijdig door meerdere threads worden gebruikt.
- Hold and Wait (Vasthouden en wachten): Threads die al een resource bezitten, wachten op een andere resource die door een andere thread wordt gebruikt.
- Geen preëmptie (No Preemption): Een resource kan niet worden afgenomen van een thread die deze bezit; alleen de thread zelf kan deze vrijgeven.
- Circulaire wacht (Circular Wait): Er bestaat een keten van twee of meer threads waarbij elke thread wacht op een resource die wordt gehouden door de volgende in de keten (circulaire wacht).
Een eenvoudig voorbeeld van een deadlock:
Twee threads, twee resources (A en B).
- Thread 1 neemt resource A.
- Thread 2 neemt resource B.
- Thread 1 probeert resource B te nemen (die door Thread 2 wordt gebruikt).
- Thread 2 probeert resource A te nemen (die door Thread 1 wordt gebruikt).
Beide threads worden voor altijd geblokkeerd.
// Eenvoudig voorbeeld van deadlock simulatie met lock
object resourceA = new object();
object resourceB = new object();
void Thread1Method()
{
lock (resourceA) // Thread 1 neemt A
{
Console.WriteLine("Thread 1 heeft resource A genomen");
Thread.Sleep(100); // Korte pauze om de mogelijkheid van threadwisseling te demonstreren
lock (resourceB) // Thread 1 probeert B te nemen
{
Console.WriteLine("Thread 1 heeft resource B genomen");
}
}
}
void Thread2Method()
{
lock (resourceB) // Thread 2 neemt B
{
Console.WriteLine("Thread 2 heeft resource B genomen");
Thread.Sleep(100); // Korte pauze
lock (resourceA) // Thread 2 probeert A te nemen
{
Console.WriteLine("Thread 2 heeft resource A genomen");
}
}
}
// Het aanmaken en starten van threads kan leiden tot een deadlock.
// new Thread(Thread1Method).Start();
// new Thread(Thread2Method).Start();
// Het uitvoeren van deze code kan, maar hoeft niet, een deadlock te demonstreren,
// omdat de volgorde van uitvoering afhangt van de scheduler.
// Als Thread 1 A neemt en Thread 2 B voordat de eerste
// B kan nemen, ontstaat een deadlock.
Het voorkomen van deadlocks wordt vaak gedaan door:
- Het ordenen van resource-acquisitie (resources altijd in dezelfde volgorde verkrijgen).
- Gebruik maken van methoden met timeout (proberen resources te verkrijgen binnen een bepaalde tijd).
- Ontwerpen zonder de noodzaak om meerdere locks gelijktijdig vast te houden.
- Gebruik maken van atomische operaties of hogere niveau primitieve synchronisatie (bijvoorbeeld
Monitor.TryEnter,ReaderWriterLockSlim).
Deadlocks zijn moeilijk te debuggen omdat ze afhangen van de volgorde van thread-uitvoering en vaak alleen onder belasting optreden. Visual Studio biedt tools voor het detecteren en analyseren ervan.