Sobes.tech
Junior

Deadlock nedir?

sobes.tech yapay zeka

AI'dan gelen yanıt

Deadlock, çok iş parçacıklı programlamada çıkış yolu olmayan bir durumdur; burada iki veya daha fazla iş parçacığı, aynı gruptaki diğer iş parçacıkları tarafından kullanılan kaynakları beklerken birbirlerini engeller.

Bir deadlock'un oluşma koşulları (Coffman koşulları):

  1. Karşılıklı dışlama (Mutual Exclusion): Kaynaklar aynı anda birden fazla iş parçacığı tarafından kullanılamaz.
  2. Tutma ve bekleme (Hold and Wait): Bir kaynak üzerinde zaten tutan iş parçacıkları, başka bir iş parçacığı tarafından tutulan başka bir kaynağı bekler.
  3. Preemption yok (No Preemption): Bir kaynak, onu kullanan iş parçacığından zorla alınamaz; sadece iş parçacığı tarafından serbest bırakılabilir.
  4. Döngüsel bekleme (Circular Wait): İki veya daha fazla iş parçacığından oluşan bir zincir vardır ve her biri, zincirdeki bir sonraki iş parçacığunun tuttuğu kaynağı bekler (döngüsel bekleme).

Basit bir deadlock örneği:

İki iş parçacığı, iki kaynak (A ve B).

  • İş parçacığı 1, kaynağı A alır.
  • İş parçacığı 2, kaynağı B alır.
  • İş parçacığı 1, B kaynağını almaya çalışır (ki bu, İş parçacığı 2 tarafından tutulmaktadır).
  • İş parçacığı 2, A kaynağını almaya çalışır (ki bu, İş parçacığı 1 tarafından tutulmaktadır).

Her iki iş parçacığı da sonsuza kadar engellenir.

// Lock kullanarak deadlock simülasyonu örneği
object resourceA = new object();
object resourceB = new object();

void Thread1Method()
{
    lock (resourceA) // İş parçacığı 1 A'yı alır
    {
        Console.WriteLine("İş parçacığı 1 kaynak A'yı aldı");
        Thread.Sleep(100); // İş parçacığı değişimini göstermek için kısa durak
        lock (resourceB) // İş parçacığı 1 B'yi almaya çalışır
        {
            Console.WriteLine("İş parçacığı 1 kaynak B'yi aldı");
        }
    }
}

void Thread2Method()
{
    lock (resourceB) // İş parçacığı 2 B'yi alır
    {
        Console.WriteLine("İş parçacığı 2 kaynak B'yi aldı");
        Thread.Sleep(100); // Kısa durak
        lock (resourceA) // İş parçacığı 2 A'yı almaya çalışır
        {
            Console.WriteLine("İş parçacığı 2 kaynak A'yı aldı");
        }
    }
}

// Thread'lerin oluşturulması ve başlatılması deadlock'a yol açabilir.
// new Thread(Thread1Method).Start();
// new Thread(Thread2Method).Start();

// Bu kodun çalıştırılması, planlayıcıya bağlı olarak, deadlock'u gösterebilir veya göstermeyebilir.
// Eğer İş parçacığı 1 A'yı alırsa ve İş parçacığı 2 B'yi alırsa, ilk
// İş parçacığı B'yi almadan önce, deadlock oluşur.

Deadlock'ları önlemek genellikle şu yollarla sağlanır:

  • Kaynakların alınma sırasını düzenlemek (her zaman aynı sırayla kaynakları almak).
  • Zaman aşımı ile kaynak alma yöntemleri kullanmak (belirli bir süre içinde kaynağı almaya çalışmak).
  • Birden fazla kilidi aynı anda tutma ihtiyacını ortadan kaldırmak.
  • Atomik işlemler veya daha yüksek seviyeli senkronizasyon primitive'leri kullanmak (örneğin, Monitor.TryEnter, ReaderWriterLockSlim).

Deadlock'lar, iş parçacıklarının çalışma sırasına bağlı oldukları ve genellikle yük altında ortaya çıktıkları için hata ayıklaması zordur. Visual Studio, bunların tespiti ve analizi için araçlar sağlar.