Bölüm 7: Kilitlenme

İşletim Sistemleri
KaynaklarDört Coffman koşuluKaynak tahsis çizgesi Bekleme çizgesiDevekuşu algoritmasıTespit algoritması KurtarmaGüvenli durumlarBankacı algoritması Önleme ve kilit sıralaması2PL, canlı kilit, açlıkJava, jstack, lockdep
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Tanım ve kaynaklar

Kilitlenmeyi tanımlamak; kesilebilir ve kesilemez kaynakları, istek–kullanım–bırakma döngüsünü ayırt etmek.

Dört koşul

Coffman koşullarını (karşılıklı dışlama, tut ve bekle, kesme yok, döngüsel bekleme) bir örnek üzerinde göstermek.

Modelleme

Kaynak tahsis ve bekleme çizgelerini çizmek; döngünün ne zaman kilitlenme anlamına geldiğini söylemek.

Tespit ve kurtarma

Matris tabanlı tespit algoritmasını elle çalıştırmak; kesme, geri sarma ve sonlandırma ile kurtarmayı karşılaştırmak.

Kaçınma

Güvenli ve güvensiz durumları ayırt etmek; Bankacı algoritmasıyla bir isteğin verilip verilmeyeceğine karar vermek.

Önleme ve pratik

Kilit sıralaması, iki aşamalı kilitleme, canlı kilit ve açlığı tanımak; Java'da kilitlenmeyi jstack ile bulmak.

Giriş

Kilitlenme Nedir?

  • Tanım (Tanenbaum): bir süreç kümesindeki her süreç, yalnızca kümedeki başka bir sürecin tetikleyebileceği bir olayı bekliyorsa küme kilitlenmiştir (deadlock).
  • Beklenen olay çoğunlukla bir kaynağın serbest bırakılmasıdır; hiçbiri çalışmadığından hiçbiri bırakamaz.
  • Örnek: S1, K1'i tutup K2'yi bekler; S2, K2'yi tutup K1'i bekler.
  • Gündelik örnek: kavşakta dört araç birbirinin önünü keser (gridlock); tek hatlı rayda karşılıklı iki tren.
  • Kilitlenen süreçler CPU harcamaz (bloke olmuşlardır) ama tuttukları kaynaklar sonsuza dek kullanılamaz.
ABCDkuyrukkuyruk

Konu yalnızca işletim sistemi değil: veritabanı işlemleri, çok iş parçacıklı uygulamalar ve dağıtık sistemler de kilitlenir.

Giriş

Kaynaklar: Kesilebilir ve Kesilemez

Kesilebilir (preemptable)

Sahibinden zarar vermeden geri alınabilir. Örnek: CPU (bağlam kaydedilir), ana bellek (sayfa diske yazılır). Kilitlenme, kaynağı yeniden dağıtarak çözülebilir.

Kesilemez (nonpreemptable)

Geri almak işlemi bozar. Örnek: yazılmakta olan Blu-ray/yazıcı işi, bir mutex, veritabanı kaydı kilidi. Kilitlenmeler bu tür kaynaklarla ilgilidir.

KaynakÖrnek sayısıTürNot
CPU çekirdeğiçokkesilebilirzamanlayıcı kesmesiyle el değiştirir
Bellek sayfasıçokkesilebilirtakas/sayfalama ile geri alınır
Mutex, semafor, dosya kilidi1kesilemezyalnızca sahibi bırakır
Veritabanı satır kilidi1kesilemez**işlem geri sarılırsa (abort) bırakılır

Her kaynak türü Ri'nin Wi tane özdeş örneği (instance) olabilir; bir istek o türün herhangi bir örneğiyle karşılanabiliyorsa örnekler özdeştir.

Giriş

Kaynak Kullanım Döngüsü

  • İste (request): kaynak boştaysa verilir; değilse süreç bloke olur (ya da hata kodu alıp sonra yeniden dener).
  • Kullan (use): süreç kaynak üzerinde işlem yapar.
  • Bırak (release): kaynak serbest kalır, bekleyenlerden biri uyandırılır.
  • İşletim sistemi bir sistem tablosunda hangi kaynağın kime verildiğini ve kimin beklediğini tutar.
İsteBırak
open()close()
malloc() / mmap()free() / munmap()
pthread_mutex_lock()pthread_mutex_unlock()
sem_wait() (down)sem_post() (up)
1. İste2. Kullan3. Bırakverildimeşgul →bloke

Giriş

Aynı Sıra ve Ters Sıra

Her kaynak bir ikili semaforla korunur: erişmeden önce down, iş bitince up. Tek süreç ya da tek kaynak varken sorun yoktur.

Kilitlenmez: ikisi de önce 1, sonra 2

void process_A(void) {
  down(&resource_1);
  down(&resource_2);
  use_both_resources();
  up(&resource_2);
  up(&resource_1);
}
void process_B(void) {
  down(&resource_1);
  down(&resource_2);
  use_both_resources();
  up(&resource_2);
  up(&resource_1);
}

Kilitlenebilir: B önce 2, sonra 1

void process_A(void) {
  down(&resource_1);
  down(&resource_2);
  use_both_resources();
  up(&resource_2);
  up(&resource_1);
}
void process_B(void) {
  down(&resource_2);  /* ters sıra */
  down(&resource_1);
  use_both_resources();
  up(&resource_1);
  up(&resource_2);
}
Eski sunumdaki “olası kilitlenme” örneğinde iki süreç de kaynakları aynı sırada alıyor, yalnızca bırakma sırası farklıydı; bu kod kilitlenmez. Kilitlenme edinme (down) sırası ters olduğunda mümkündür (Tanenbaum Şekil 6-2b).

Giriş · Kodu adım adım çalıştır

Ters Sırada Edinim: Adım Adım

semaphore r1 = 1, r2 = 1;
void A(void) {
  down(&r1);
  down(&r2);
  use_both();
  up(&r2); up(&r1);
}
void B(void) {
  down(&r2);
  down(&r1);
  use_both();
  up(&r1); up(&r2);
}
ABr1r2

İki ikili semafor 1 ile başlar: iki kaynak da boş.

ABr1r2

A down(&r1) yapar ve r1'i alır (r1 → A kenarı).

ABr1r2

Zamanlayıcı B'ye geçer; B down(&r2) ile r2'yi alır.

ABr1r2

B r1'i ister; r1 A'da olduğu için B bloke olur (kesikli istek kenarı).

ABr1r2

A r2'yi ister; r2 B'de, A da bloke olur.

ABr1r2döngü: A → r2 → B → r1 → A

Çizgede döngü oluştu. up satırlarına hiçbiri ulaşamaz: kilitlenme.

Kilitlenme her çalıştırmada oluşmaz: A iki down'u B başlamadan bitirirse sorun çıkmaz. Bu yüzden testte nadiren görülür, üretimde ortaya çıkar.

Kilitlenme Koşulları

Kilitlenmenin Dört Koşulu (Coffman, 1971)

1. Karşılıklı dışlama

Kaynak ya tam olarak bir sürece atanmıştır ya da boştur; aynı anda paylaşılamaz.

2. Tut ve bekle

Bir süreç en az bir kaynağı tutarken başkasının tuttuğu yeni kaynakları ister ve bekler.

3. Kesme yok (no preemption)

Verilmiş bir kaynak zorla geri alınamaz; yalnızca tutan süreç kendi isteğiyle bırakır.

4. Döngüsel bekleme

T0, T1'in; T1, T2'nin; …; Tn, T0'ın tuttuğu kaynağı bekler.

Dört koşul birlikte gereklidir: biri bile yoksa kilitlenme olamaz. Bu, “önleme” stratejisinin temelidir. İlk üçü sistemin politikasıdır; dördüncüsü o anki durumdur. Her türden tek örnek varsa dört koşul aynı zamanda yeterlidir.

Kilitlenme Koşulları

Dört Koşul Bir Arada

  • Kavşağın dört karesi = dört kesilemez kaynak; araçlar = süreçler.
  • Her adımda bir koşulu işaretleyin.
  • Herhangi bir koşulu kırmak çözümdür:
    • trafik polisi bir aracı geri çektirir (kesme),
    • “kavşak boşalmadan girme” kuralı (tut ve bekle yok),
    • trafik ışığı (sıralama, döngü yok).
ABCDkuyrukkuyrukbir kareye aynı anda tek araç

Karşılıklı dışlama: bir kavşak karesinde aynı anda yalnızca bir araç bulunabilir.

ABCDkuyrukkuyruk

Tut ve bekle: her araç bulunduğu kareyi tutarken önündeki kareyi bekliyor (turuncu oklar).

ABCDkuyrukkuyrukhiçbir araç geri çekilemez

Kesme yok: arkada kuyruk var; hiçbir araç kareyi boşaltmak için geri çekilemez.

ABCDkuyrukkuyruk

Döngüsel bekleme: A → B → C → D → A. Dört koşul birlikte: trafik kilitlendi.

Modelleme

Kaynak Tahsis Çizgesi

  • Holt (1972): iki tür düğüm; süreçler daire, kaynaklar kare. Çok örnekli kaynakta karenin içinde her örnek için bir nokta.
  • Atama kenarı R → P: R, P'ye verilmiş. İstek kenarı P → R: P, R'yi bekliyor (bu sunumda kesikli turuncu).
  • İstek karşılandığında istek kenarı atama kenarına dönüşür; bırakıldığında silinir.
AR(a) A, R'yi tutuyorBS(b) B, S'yi istiyorCDUT(c) Kilitlenme: C → U → D → T → C

Tanenbaum MOS Şekil 6-3. Silberschatz aynı modeli “resource-allocation graph” olarak T (thread) düğümleriyle çizer.

Modelleme

Kilitlenme Nasıl Oluşur?

A        B        C
R iste   S iste   T iste
S iste   T iste   R iste
R bırak  S bırak  T bırak
S bırak  T bırak  R bırak

İşletim sistemi istekleri geldiği sırada karşılarsa: R, S, T verilir, sonra her süreç bir sonrakinin kaynağını ister.

ABCRST

Başlangıç: üç kaynak da boş. Sıralı (round-robin) zamanlama varsayılıyor.

ABCRST

1. A, R'yi ister ve alır.

ABCRST

2. B, S'yi ister ve alır.

ABCRST

3. C, T'yi ister ve alır.

ABCRST

4. A, S'yi ister: S, B'de → A bloke.

ABCRST

5. B, T'yi ister: T, C'de → B bloke.

ABCRSTdöngü A→S→B→T→C→R→A

6. C, R'yi ister: R, A'da → C bloke. Döngü kapandı: kilitlenme.

Tanenbaum MOS Şekil 6-4 (a)–(j). Gerçekte zamanlayıcı başka bir sıra da seçebilirdi; kilitlenme sıralamaya bağlıdır.

Modelleme

Kilitlenme Nasıl Önlenebilir?

A        B        C
R iste   S iste   T iste
S iste   T iste   R iste
R bırak  S bırak  T bırak
S bırak  T bırak  R bırak

İS, bir isteği vermenin kilitlenmeye yol açacağını önceden bilseydi, B'yi bekleterek tehlikeli sırayı engelleyebilirdi.

ABCRST

İS, B'nin isteklerini bir süre askıya alır (B'yi zamanlamaz). Sadece A ve C çalışır.

ABCRST

1. A, R'yi ister ve alır.

ABCRST

2. C, T'yi ister ve alır.

ABCRST

3. A, S'yi ister ve alır (S boş).

ABCRST

4. C, R'yi ister: R, A'da → C bloke. Döngü yok, A ilerleyebilir.

ABCRST

5. A, R'yi bırakır → R, C'ye verilir; C ilerler.

ABCRST

6. A, S'yi bırakıp biter. Artık B çalıştırılabilir: S'yi alır, T'yi C bitince alır. Kilitlenme yok.

Tanenbaum MOS Şekil 6-4 (k)–(q). “Hangi isteği ertelemeli?” sorusu, ilerideki kaçınma (Bankacı algoritması) konusunun özüdür.

Modelleme

Çok Örnekli Kaynaklar

  • Kaynak kümeleri: R1 ×1, R2 ×2, R3 ×1, R4 ×3.
  • T1: bir R2 örneğini tutar, R1'i bekler.
  • T2: R1'i ve bir R2 örneğini tutar, R3'ü bekler.
  • T3: R3'ü tutar.
  • Atama kenarı karedeki noktadan (örnekten) çıkar; istek kenarı karenin kendisine gider.
  • Çizgede döngü yok → kilitlenme yok: T3 bitince R3'ü bırakır, T2 sonra T1 ilerler.
R1R3T1T2T3R2R4

Silberschatz 10e Şekil 8.4. R4'ün üç örneği de boşta.

Modelleme

Döngü ve Kilitlenme

  • Tek bir istek kenarı (T3 → R2) iki döngü oluşturur.
  • T3, T1 ya da T2'nin bir R2 bırakmasını bekler; T2, T3'ün R3'ünü; T1, T2'nin R1'ini.
  • Döngüdeki her süreç döngüdeki bir başkasını bekliyor ve dışarıdan bir “kurtarıcı” yok.
R1R3T1T2T3R2R4

Önceki durum: döngü yok.

R1R3T1T2T3R2R4

T3, bir R2 örneği ister. İki örnek de dolu (T1 ve T2'de) → T3 bloke.

R1R3T1T2T3R2R4

Döngü 1: T1 → R1 → T2 → R3 → T3 → R2 → T1.

R1R3T1T2T3R2R4T1, T2, T3 kilitlendi

Döngü 2: T2 → R3 → T3 → R2 → T2. R2'nin her iki örneğinin sahibi de döngüde → kilitlenme.

Silberschatz 10e Şekil 8.5.

Modelleme

Döngü Var, Kilitlenme Yok

  • Kaynak türlerinin birden çok örneği varsa döngü gerekli ama yeterli değildir.
  • Döngü dışındaki bir süreç (T2 ya da T4) bitip örneğini bırakınca döngü çözülür.
  • Bu yüzden çok örnekli durumda çizgede döngü aramak yetmez; matris tabanlı bir algoritma gerekir.
T1R1T2T3R2T4

T1 bir R1 ister; R1'in iki örneği T2 ve T3'te. T3 bir R2 ister; R2'nin örnekleri T1 ve T4'te.

T1R1T2T3R2T4

Döngü var: T1 → R1 → T3 → R2 → T1. Ama T2 ve T4 döngünün dışında ve hiçbir şey beklemiyor.

T1R1T2T3R2T4

T4 işini bitirip R2 örneğini bırakır → örnek T3'e verilir. Döngü kırıldı: kilitlenme yoktu.

Silberschatz 10e Şekil 8.6.

Modelleme

Döngü Kuralı

ÇizgeHer kaynak türünde tek örnekBazı türlerde birden çok örnek
Döngü yokKilitlenme yokKilitlenme yok
Döngü varKilitlenme var (döngü ⇔ kilitlenme)Kilitlenme olabilir; döngü gerekli ama yeterli değil
Tek örnek

Döngü arama yeterli: DFS ile O(V + E). Döngüdeki süreçler kilitlenmiştir.

Çok örnek

Döngü yalnızca bir uyarıdır. Kesin karar için tahsis/istek matrisleriyle “herkes bitebilir mi?” diye sorulur.

Döngüsel bekleme koşulu, döngü içeren çizgenin karşılığıdır; tek örnekli kaynaklarda dört koşulun birlikte varlığı kilitlenmeyi garanti eder.

Modelleme

Bekleme (Wait-For) Çizgesi

P1P2P3P4R2R3R1R4

Tek örnekli kaynaklarla bir tahsis çizgesi: P1 R1'i tutar R2'yi ister, P2 R2'yi tutar R3'ü ister, P3 R3'ü tutar R1'i ister, P4 R4'ü tutar R2'yi ister.

P1P2P3P4R2R3R1R4

Her Pi → R → Pj yolu tek bir Pi → Pj kenarına daraltılır (kırmızı): “Pi, Pj'yi bekliyor”.

P1P2P3P4

Kaynak düğümleri silinir: bekleme (wait-for) çizgesi.

P1P2P3P4döngü: P1→P2→P3→P1P4 döngüde değil amaP2'yi beklediği için o dasonsuza dek bekler

Bekleme çizgesinde döngü ⇔ kilitlenme. Algoritma çizgeyi periyodik tarar; maliyet O(n²) (n: süreç sayısı).

Yalnızca her türden tek örnek olduğunda kullanılabilir. Veritabanları (ör. PostgreSQL, MySQL InnoDB) kilit bekleme çizgesinde döngü arayarak kilitlenme tespit eder.

Stratejiler

Kilitlenmelerle Başa Çıkma Stratejileri

1. Görmezden gel

“Devekuşu algoritması”. Kilitlenme nadir ve önleme maliyeti yüksekse sorunu yok sayıp gerekirse yeniden başlat. Linux ve Windows genel kaynaklar için bunu yapar.

2. Tespit et ve kurtar

Tepkisel. Kilitlenmeye izin ver, periyodik olarak tespit et, sonra kesme, geri sarma ya da sonlandırma ile çöz.

3. Dinamik kaçınma

Önleyici, çalışma anında. Her isteği, sistemi güvensiz duruma sokacaksa ertele (Bankacı). Azami ihtiyaçların önceden bilinmesini ister.

4. Önleme

Önleyici, tasarım anında. Dört koşuldan en az birini yapısal olarak imkânsız kıl (ör. kilit sıralaması).

Eski sunumda “kurtarma” ayrı bir dördüncü teknik olarak sayılıyordu; kurtarma, tespitin ikinci yarısıdır. Görmezden gelme ise listede eksikti.

Stratejiler

Devekuşu Algoritması

  • Strateji: hiçbir şey yapma. Kilitlenme olursa kullanıcı/yönetici süreci öldürür ya da sistemi yeniden başlatır.
  • Mühendislik dengesi: kilitlenme yılda bir kez oluyor, çökmeler ve donanım hataları ise çok daha sık görülüyorsa, pahalı ve kısıtlayıcı önlemler değmez.
  • Genel amaçlı İS'ler (Linux, Windows, macOS) kullanıcı süreçlerinin kilitleri, dosya kilitleri, boru (pipe) beklemeleri için bunu uygular; sorumluluk uygulama geliştiricisindedir.
  • Ama İS kendi içinde kilitlenmeye karşı önlem alır: çekirdek kilit sıralaması, lockdep denetimi.
  • Gerçek zamanlı ve güvenlik-kritik sistemlerde kabul edilemez.
“Kilitlenme mi? Ne kilitlenmesi?”
Eski sunumdaki “normal mod / pasif mod” anlatımı ve “tespit ile kaçınma arasında denge kurar” ifadesi yanlıştı: devekuşu yaklaşımı ne tespit ne kaçınma yapar; yalnızca maliyet–olasılık karşılaştırmasıdır.

Tespit ve Kurtarma

Tespit: Her Türden Tek Kaynak

  • A: R'yi tutar, S'yi ister. B: T'yi ister.
  • C: S'yi ister. D: U'yu tutar, S ve T'yi ister.
  • E: T'yi tutar, V'yi ister. F: W'yi tutar, S'yi ister.
  • G: V'yi tutar, U'yu ister.
  • Soru: sistem kilitlenmiş mi, kilitlendiyse hangi süreçler?
  • Çizgede döngü: D → T → E → V → G → U → D. D, E, G kilitli.
  • A, C, F kilitli değil: S boşta; biri alır, bitirir, bırakır. B ise döngüdeki T'yi beklediği için ilerleyemez (döngüde olmasa da takılı).
RABCSDTEFUVWG

Tanenbaum MOS Şekil 6-5. Göz ile kolay; yüzlerce düğümlü bir çizgede sistematik bir algoritma gerekir.

Tespit ve Kurtarma

Döngü Arama Algoritması (DFS)

  1. Çizgedeki her N düğümü için 2–6. adımları N'den başlayarak uygula.
  2. L'yi boş liste yap; tüm kenarları işaretsiz say.
  3. Geçerli düğümü L'nin sonuna ekle. Düğüm L'de iki kez geçiyorsa çizgede döngü vardır: L'deki döngüyü raporla, dur.
  4. Geçerli düğümden çıkan işaretsiz kenar var mı? Varsa 5'e, yoksa 6'ya git.
  5. Rastgele bir işaretsiz kenar seç, işaretle, gösterdiği düğüme geç; 3'e dön.
  6. Başlangıç düğümündeysek bu N'den erişilebilen döngü yoktur. Değilsek çıkmaz sokaktayız: düğümü L'den çıkar, önceki düğüme dön, 3'e git.
Özünde

Her düğümden başlayan bir derinlik öncelikli arama; yığın görevini L listesi görür.

Maliyet

Basit sürüm her düğümden yeniden başladığı için O(V·(V+E)); renkli DFS (beyaz/gri/siyah) tek geçişte O(V+E).

Çıktı

L'nin tekrar eden düğümden sonraki kısmı döngüdür; içindeki süreçler kilitlenmiştir.

Tespit ve Kurtarma

Döngü Arama: Adım Adım

  • Düğümler alfabetik sırayla başlangıç alınır: R, A, B, …
  • Turuncu düğümler o anki L listesinde; kırmızı çerçeve geçerli düğüm.
  • Kenar seçimi “rastgele” olabilir; burada önce S, sonra T seçiliyor.
RABCSDTEFUVWGL = [R]

R'den başla. L = [R]. Tek çıkış R → A.

RABCSDTEFUVWGL = [R, A, S]

R → A → S. S'den çıkan kenar yok: çıkmaz sokak.

RABCSDTEFUVWGL = []

S, sonra A ve R L'den çıkarılır; R'ye dönüldü: R'den döngü yok. Sonra A'dan başlanır (yine yok)…

RABCSDTEFUVWGL = [B, T, E]

B'den başla: B → T → E.

RABCSDTEFUVWGL = [B, T, E, V, G, U]

E → V → G → U. Hâlâ tekrar yok.

RABCSDTEFUVWGL = [B, T, E, V, G, U, D, S]

U → D. D'den önce S denenir: çıkmaz sokak, S L'den çıkar.

RABCSDTEFUVWGL = [B, T, E, V, G, U, D, T]

D → T: T, L'de ikinci kez → döngü: T, E, V, G, U, D. Algoritma durur.

Tespit ve Kurtarma

Tespit: Her Türden Çok Kaynak

Var olan kaynaklarE = (E₁, E₂, E₃, …, Eₘ)Boştaki kaynaklarA = (A₁, A₂, A₃, …, Aₘ)Tahsis matrisi CC₁₁ C₁₂ C₁₃ … C₁ₘC₂₁ C₂₂ C₂₃ … C₂ₘ ⋮ ⋮Cₙ₁ Cₙ₂ Cₙ₃ … Cₙₘ← 1. sürecin elindekilerİstek matrisi RR₁₁ R₁₂ R₁₃ … R₁ₘR₂₁ R₂₂ R₂₃ … R₂ₘ ⋮ ⋮Rₙ₁ Rₙ₂ Rₙ₃ … Rₙₘ← 2. sürecin istekleriDeğişmez: Σᵢ Cᵢⱼ + Aⱼ = Eⱼ (her j kaynak türü için)
  • n süreç, m kaynak türü. C'nin i. satırı Pi'nin şu an tuttuğu, R'nin i. satırı Pi'nin şu an istediği kaynaklardır.
  • Vektör karşılaştırması: X ≤ Y ancak ve ancak her j için Xj ≤ Yj. Ör. (1 0 1 0) ≤ (2 1 0 0) değil.

Tanenbaum MOS Şekil 6-6. Silberschatz aynı yapıları Available, Allocation, Request adlarıyla verir.

Tespit ve Kurtarma

Tespit Algoritması

A ← boş kaynak vektörü
tüm Pi işaretsiz
tekrarla:
  Ri ≤ A olan işaretsiz bir Pi bul
  bulunamazsa: çık
  A ← A + Ci   /* Pi biter, bırakır */
  Pi'yi işaretle
işaretsiz Pi'ler kilitlenmiştir
  • Fikir: isteği şu anki boş kaynaklarla karşılanabilen bir süreç bitebilir; bitince tuttuklarını geri verir.
  • Bu iyimser bir varsayımdır: süreç ek kaynak istemeden bitecek sayılır. Yanılırsa sonraki çalıştırmada yakalanır.
  • Sonda işaretsiz kalanlar kilitlenmiştir.
  • Karmaşıklık: O(m · n²).
Eski sunumda “C'nin i. satırına A'yı ekle” yazıyordu; doğrusu tersidir: A ← A + Cᵢ (biten sürecin tuttukları boş havuza döner).

Tespit ve Kurtarma · Algoritmayı adım adım çalıştır

Tespit Örneği

A ← (2 1 0 0)
tüm Pi işaretsiz
tekrarla:
  Ri ≤ A olan işaretsiz Pi bul
  bulunamazsa: çık
  A ← A + Ci
  Pi'yi işaretle
işaretsizler kilitli
C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A2100E = (4 2 3 1)

Teyp (Tp), çizici (Pl), tarayıcı (Tr), CD. E = (4 2 3 1), boşta A = (2 1 0 0).

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A2100E = (4 2 3 1)(2 0 0 1) ≤ (2 1 0 0)? CD yok ✗

P1: R₁ = (2 0 0 1). Boş CD yok → şimdilik bitemez.

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A2100E = (4 2 3 1)(1 0 1 0) ≤ (2 1 0 0)? tarayıcı yok ✗

P2: R₂ = (1 0 1 0). Boş tarayıcı yok ✗.

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A2100E = (4 2 3 1)(2 1 0 0) ≤ (2 1 0 0) ✓

P3: R₃ = (2 1 0 0) ≤ A ✓. P3 çalışıp bitebilir.

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A2220E = (4 2 3 1)

P3 biter, tuttuğu C₃ = (0 1 2 0) geri gelir: A = (2 2 2 0).

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A2220E = (4 2 3 1)CD hâlâ yok ✗

Yeni tur. P1 yine bekler (CD = 0).

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A4221E = (4 2 3 1)

P2: (1 0 1 0) ≤ (2 2 2 0) ✓ → biter, C₂ = (2 0 0 1) döner: A = (4 2 2 1).

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A4231E = (4 2 3 1)

P1: (2 0 0 1) ≤ (4 2 2 1) ✓ → biter: A = (4 2 3 1) = E.

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32100A4231E = (4 2 3 1)sıra: P3 → P2 → P1

Tüm süreçler işaretlendi: kilitlenme yok.

Tanenbaum MOS Şekil 6-7. Bulunan sıra (P3, P2, P1), algoritmanın satırları hangi sırayla taradığına bağlıdır; sonuç değişmez.

Tespit ve Kurtarma

Bir İstek Fazlası: Kilitlenme

  • Tek bir hücrenin (R₃'teki CD) değişmesi sonucu tamamen değiştirir.
  • İlk turda hiçbir satır karşılanamazsa algoritma hemen biter.
  • Çok örnekli kaynakta çizge yerine bu tarama kullanılır; döngü bilgisi kendiliğinden gelir.
C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32101A2100E = (4 2 3 1)

Aynı durum, tek fark: P3 iki teyp ve bir çiziciye ek olarak bir CD de istiyor: R₃ = (2 1 0 1).

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32101A2100E = (4 2 3 1)P1 ✗ (CD yok)

P1 ✗ (CD gerekli, boşta yok).

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32101A2100E = (4 2 3 1)P2 ✗ (tarayıcı yok)

P2 ✗ (tarayıcı gerekli, boşta yok).

C (tutulan)TpPlTrCDP10010P22001P30120R (istek)TpPlTrCDP12001P21010P32101A2100E = (4 2 3 1)P3 ✗ → P1, P2, P3 kilitli

P3 ✗ (CD tek ve P2'de). Hiçbir satır karşılanamıyor: üç süreç de kilitlenmiş.

Tespit ve Kurtarma

Tespit Ne Zaman Çalıştırılmalı?

Her istekte

Bekletilen her istekten sonra. Kilitlenme anında, suçlu istekle birlikte bulunur; ama CPU maliyeti yüksektir.

Periyodik

Her k dakikada bir. Ucuzdur; kilitlenme bir süre fark edilmeden kalır, döngüye başka süreçler de takılabilir.

Belirtiye göre

CPU kullanımı belirli bir eşiğin altına düştüğünde ya da bir kilit beklemesi uzadığında.

  • Ne sıklıkla? Kilitlenmenin ne kadar olası olduğuna ve kaç sürecin etkileneceğine bağlı.
  • Örnek: PostgreSQL bir kilidi deadlock_timeout (varsayılan 1 sn) kadar bekleyen işlem için bekleme çizgesini tarar; döngü bulursa bir işlemi iptal eder (ERROR: deadlock detected).
  • Eski sunumda tespit için “önemli bir yük getirmez” deniyordu: yük, çalıştırma sıklığıyla doğru orantılıdır; ayrıca kurtarmanın maliyeti (kaybolan iş) de hesaba katılmalıdır.

Tespit ve Kurtarma

Kilitlenmeden Kurtarma

Kaynak kesme

Bir kaynağı sahibinden geçici olarak alıp başka sürece ver (ör. yazıcı işini kenara alıp kâğıtları ayırmak). Kaynağın doğasına bağlı; çoğu zaman elle ya da imkânsız.

Geri sarma (rollback)

Süreçler periyodik olarak denetim noktası (checkpoint) kaydeder. Kurban, kaynağı almadan önceki noktaya döndürülür; sonraki iş kaybolur. Veritabanlarında işlem iptali (abort) budur.

Sonlandırma (killing)

En kaba yöntem. Ya döngüdeki tüm süreçler ya da döngü kırılana kadar teker teker (her öldürmeden sonra tespit yeniden çalışır). Döngü dışından bir süreç de seçilebilir.

Kurban seçimi (en düşük maliyet): öncelik, ne kadar çalıştığı ve ne kadar kaldığı, tuttuğu kaynak sayısı, bitmek için kaç kaynak daha istediği, etkileşimli mi toplu mu, yeniden başlatılabilir mi (ör. derleme evet, veritabanı güncellemesi dikkat). Aynı süreç sürekli kurban seçilirse açlık: geri sarma sayısını maliyete ekle.

Eski sunumda kurtarma listesine önleme ve tespit de karışmıştı; “önemli bir kesinti olmadan kurtarma” ifadesi de iyimserdi: her kurtarma yöntemi kaybedilen iş ya da yeniden çalıştırma maliyeti getirir.

Tespit ve Kurtarma

Kurtarma: Adım Adım

P1P2P3P4R2R3R1R4tespit: döngü

Tespit algoritması P1 → R2 → P2 → R3 → P3 → R1 → P1 döngüsünü buldu. P4 de R2'yi beklediği için takılı.

P1P2P4R2R3R1R4✕ P3kurban: P3R3 ve R1 isteğiserbest

Kurban: en az iş kaybettirecek süreç, P3. Sonlandırılır (ya da denetim noktasına geri sarılır); tuttuğu R3 serbest kalır.

P1P2P4R2R3R1R4R3 → P2P2 çalışır, biter

R3 bekleyen P2'ye verilir. P2 işini bitirip R2 ve R3'ü bırakır.

P1P4R2R3R1R4R2 → P1, sonra P4P3 yeniden başlatılır

R2 sıradaki bekleyene (P1) verilir; P1 bitince P4. P3 baştan (ya da denetim noktasından) yeniden çalıştırılır.

Teker teker sonlandırmada her kurbandan sonra tespit algoritması yeniden çalışır; döngü kırılınca durulur.

Kaçınma

Kaynak Yörüngeleri

  • A: I1–I3 arası yazıcı, I2–I4 arası çizici kullanır.
  • B: I5–I7 arası çizici, I6–I8 arası yazıcı kullanır.
  • Taralı bölgeler karşılıklı dışlama nedeniyle girilemez.
  • Kaçınma = yörüngeyi güvensiz bölgeye sokacak isteği ertelemek.
ikisi de yazıcıikisi de çiziciABI1I2I3I4I5I6I7I8A: yazıcı [I1,I3], çizici [I2,I4]

Yatay eksen A'nın, dikey eksen B'nin yürüttüğü komutlar. Tek CPU: yörünge yalnızca sağa (A çalışır) ya da yukarı (B çalışır) ilerler.

ikisi de yazıcıikisi de çiziciABI1I2I3I4I5I6I7I8A: yazıcı [I1,I3], çizici [I2,I4]pqrst

p → q: A çalışır; q → r: B çalışır; r → s: A yazıcıyı alır (I1). s → t: B ilerler, I5'te çiziciyi isteyecek.

ikisi de yazıcıikisi de çizicigüvensizABI1I2I3I4I5I6I7I8A: yazıcı [I1,I3], çizici [I2,I4]pqrst

Kırmızı kutuya girilirse A yazıcıyı, B çiziciyi tutar ve ikisi de taralı bölgeye girmek zorundadır: kilitlenme kaçınılmaz. Bu bölge güvensizdir.

ikisi de yazıcıikisi de çizicigüvensizABI1I2I3I4I5I6I7I8A: yazıcı [I1,I3], çizici [I2,I4]pqrstu

t noktasında İS, B'nin çizici isteğini erteler; A I4'e kadar çalışıp ikisini de bırakır. Sonra B devam eder: kilitlenme yok.

Tanenbaum MOS Şekil 6-8 (Dijkstra'nın iki süreçli gösterimi).

Kaçınma

Güvenli ve Güvensiz Durumlar

  • Durum: E, A, C ve azami ihtiyaçlar (Max) ile belirlenir.
  • Güvenli durum: her süreç anında azami isteğini yapsa bile, tüm süreçleri bir sırayla sonuna kadar çalıştırabilecek bir güvenli dizi <P1, …, Pn> vardır.
  • Pi'nin kalan ihtiyacı ≤ boştakiler + Pj (j < i) tarafından tutulanlar.
  • Güvensiz ≠ kilitlenmiş. Güvensiz durumda henüz kilitlenme yoktur; süreçler azami isteğini yapmazsa her şey yolunda gidebilir. Ama sistem artık bitişi garanti edemez.
  • Kaçınma algoritması sistemi her zaman güvenli durumda tutar.
güvenligüvensizkilitlenme

Kaçınma

Güvenli Durum Örneği

  • Tek kaynak türü, 10 örnek.
  • Has: şu an tutulan; Max: bitene kadar gerekecek en çok.
  • Kalan ihtiyaç = Max − Has.
  • İS her adımda isteklerin dizisini kendisi seçebilecek konumdadır.
HasMaxA39B24C27Boş: 3

(a) Toplam 10 örnek; 7'si dağıtılmış, 3 boş. Güvenli mi? Bir güvenli dizi arayalım.

HasMaxA39B44C27Boş: 1

(b) B'nin kalan ihtiyacı 2 ≤ 3: B'ye 2 verilir, B azamisine ulaşır.

HasMaxA39B0–C27Boş: 5

(c) B biter ve 4 örneği bırakır: boş 5.

HasMaxA39B0–C77Boş: 0

(d) C'nin kalan ihtiyacı 5 ≤ 5: C'ye 5 verilir.

HasMaxA39B0–C0–Boş: 7güvenli dizi: B, C, A

(e) C biter: boş 7. A'nın kalan 6'sı karşılanır. B → C → A güvenli dizisi var: durum güvenli.

Tanenbaum MOS Şekil 6-9.

Kaçınma

Güvensiz Durum Örneği

  • Fark tek bir karar: (a)'da A'ya fazladan bir örnek vermek.
  • (b) henüz kilitlenme değildir. A, ek isteğini yapmadan bir kaynağı bırakırsa sorun çıkmayabilir.
  • Ama İS en kötü durumu varsayar: herkes azami isteğini yaparsa bitiş garanti değil.
HasMaxA39B24C27Boş: 3

Aynı başlangıç (güvenli). Şimdi A bir örnek daha ister ve İS bunu verir.

HasMaxA49B24C27Boş: 2

(b) A: 4/9, boş 2. Güvenli dizi var mı?

HasMaxA49B44C27Boş: 0

(c) Yalnızca B bitebilir (ihtiyaç 2 ≤ 2): B'ye 2 verilir.

HasMaxA49B0–C27Boş: 4A 5, C 5 istiyor; boş 4

(d) B biter: boş 4. A'nın 5, C'nin 5 ihtiyacı var: hiçbiri garanti edilemez. (b) durumu güvensizdi; A'nın isteği ertelenmeliydi.

Tanenbaum MOS Şekil 6-10.

Kaçınma

Bankacı Algoritması: Tek Kaynak

  • Her istekte: “Bu isteği verirsem durum güvenli kalır mı?”
  • Evet → ver. Hayır → ertele (süreç bekler, istek sonra yeniden değerlendirilir).
  • Güvenlik: kalan ihtiyacı boştakilerle karşılanabilen bir müşteri bul, bitmiş say, kredisini kasaya ekle; tekrarla.
HasMaxA06B05C04D07Boş: 10Max toplamı 22 > 10, yine de güvenli

(a) Bankacı (Dijkstra, 1965): kasada 10 birim, 4 müşterinin kredi limitleri toplamı 22. Herkes aynı anda azami istemez.

HasMaxA16B15C24D47Boş: 2güvenli dizi: C, D, A, B

(b) Boş 2. C'nin ihtiyacı 2 ≤ 2 → C biter (boş 4), sonra D (3 ≤ 4 → boş 8), A, B. Güvenli.

HasMaxA16B25C24D47Boş: 1hiçbir ihtiyaç ≤ 1 değil: güvensiz

(c) (b)'deyken B bir birim daha isterse: boş 1, en küçük ihtiyaç 2. Güvensiz → istek reddedilip B bekletilmelidir.

Düzeltme: durum, “kilitlenmeden sonlanan bir süreç varsa” değil, tüm süreçler bir sırayla bitebiliyorsa güvenlidir. Bankacı ayrıca kilitlenmeyle “sona ermez”: sistemi hiç kilitlenmeye sokmaz.

Kaçınma

Bankacı Algoritması: Çoklu Kaynak

  • Available[m]: her türden boş örnek.
  • Max[n][m]: her sürecin önceden bildirdiği azami istek.
  • Allocation[n][m]: şu an tutulan.
  • Need = Max − Allocation: kalan ihtiyaç.
/* güvenlik algoritması */
Work ← Available
Finish[i] ← false  (tüm i)
while Finish[i] = false ve
      Need[i] ≤ Work olan i var:
  Work ← Work + Allocation[i]
  Finish[i] ← true
tüm i için Finish[i] ise GÜVENLİ
/* Ti, Request[i] isterse */
if Request[i] > Need[i]:
  hata  /* Max aşıldı */
if Request[i] > Available:
  Ti bekler  /* kaynak yok */
/* varmış gibi yap: */
Available  -= Request[i]
Allocation[i] += Request[i]
Need[i]    -= Request[i]
if güvenli: isteği ver
else: geri al, Ti bekler

Karmaşıklık: güvenlik testi O(m · n²); her istekte çalışır.

Kaçınma · Algoritmayı adım adım çalıştır

Güvenlik Algoritması: Örnek

Work ← Available
Finish[i] ← false
for i = T0 … T4 (tekrar tekrar):
  if Finish[i] = false and
     Need[i] ≤ Work:
    Work ← Work + Allocation[i]
    Finish[i] ← true
if tüm Finish[i]: GÜVENLİ
AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work332WorkSıra: —

A=10, B=5, C=7 örnek. Available = (3 3 2). Need = Max − Allocation hesaplandı.

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work332WorkSıra: —(7 4 3) ≤ (3 3 2)? ✗

T0: Need (7 4 3) ≤ (3 3 2)? Hayır, geç.

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work532WorkSıra: T1(1 2 2) ≤ (3 3 2) ✓ Work += (2 0 0)

T1: (1 2 2) ≤ (3 3 2) ✓ → biter, Work = (3 3 2) + (2 0 0) = (5 3 2).

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work532WorkSıra: T1(6 0 0) ≤ (5 3 2)? ✗

T2: (6 0 0) ≤ (5 3 2)? A yetmez ✗.

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work743WorkSıra: T1 → T3(0 1 1) ≤ (5 3 2) ✓ Work += (2 1 1)

T3: (0 1 1) ✓ → Work = (7 4 3).

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work745WorkSıra: T1 → T3 → T4(4 3 1) ≤ (7 4 3) ✓ Work += (0 0 2)

T4: (4 3 1) ✓ → Work = (7 4 5).

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work755WorkSıra: T1 → T3 → T4 → T0ikinci tur: T0 (7 4 3) ≤ (7 4 5) ✓

İkinci tur. T0: (7 4 3) ≤ (7 4 5) ✓ → Work = (7 5 5).

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work1057WorkSıra: T1 → T3 → T4 → T0 → T2T2 (6 0 0) ≤ (7 5 5) ✓ Work = toplam

T2: (6 0 0) ✓ → Work = (10 5 7), yani tüm kaynaklar.

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Work1057WorkSıra: T1 → T3 → T4 → T0 → T2GÜVENLİ

Tüm Finish true: durum güvenli. <T1, T3, T4, T2, T0> gibi başka güvenli diziler de vardır.

Silberschatz 10e §8.6.3.3 örneği. Max: T0 (7 5 3), T1 (3 2 2), T2 (9 0 2), T3 (2 2 2), T4 (4 3 3).

Kaçınma

İstek Kabul: T1 (1 0 2)

  • Üç adım: Need kontrolü, Available kontrolü, güvenlik testi.
  • Güvenlik testi “varmış gibi” durumda yapılır; durum güvensiz çıksaydı değişiklikler geri alınırdı.
  • Hesaplar: Python betiğiyle doğrulandı.
AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Avail332AvailRequest₁ = (1 0 2) ≤ Need₁ = (1 2 2) ✓

T1, (1 0 2) ister. 1. kontrol: bildirdiği azami ihtiyacı aşmıyor ✓.

AllocationABCT0010T1200T2302T3211T4002NeedABCT0743T1122T2600T3011T4431Avail332Avail(1 0 2) ≤ Available = (3 3 2) ✓

2. kontrol: kaynaklar şu an boşta ✓. Ama bu tek başına yetmez.

AllocationABCT0010T1302T2302T3211T4002NeedABCT0743T1020T2600T3011T4431Avail230Availvarmış gibi: Avail (2 3 0), Alloc₁ (3 0 2), Need₁ (0 2 0)

İsteği vermiş gibi yeni durumu hesapla.

AllocationABCT0010T1302T2302T3211T4002NeedABCT0743T1020T2600T3011T4431Work1057WorkSıra: T1 → T3 → T4 → T0 → T2yeni durum güvenli → istek VERİLİR

Güvenlik algoritması yeni durumda <T1, T3, T4, T0, T2> dizisini bulur: güvenli → istek verilir.

Kaçınma

İstek Reddi: T4 (3 3 0) ve T0 (0 2 0)

  • Bekleme nedeni 1: kaynak yok (T4).
  • Bekleme nedeni 2: kaynak var ama vermek durumu güvensiz yapar (T0).
  • Kaçınmanın bedeli budur: kaynaklar bazen boşta beklerken istek ertelenir; kullanım oranı düşer.
AllocationABCT0010T1302T2302T3211T4002NeedABCT0743T1020T2600T3011T4431Avail230AvailT4: (3 3 0) ≤ Avail (2 3 0)? ✗ → bekle

T1'in isteği verildikten sonra T4, (3 3 0) ister. Need'i aşmıyor ama A türünden yalnızca 2 boş: T4 bekler.

AllocationABCT0010T1302T2302T3211T4002NeedABCT0743T1020T2600T3011T4431Avail230AvailT0: (0 2 0) ≤ Need₀ ✓ ve ≤ Avail (2 3 0) ✓

T0, (0 2 0) ister. İki kontrol de geçer; kaynak fiilen boşta.

AllocationABCT0030T1302T2302T3211T4002NeedABCT0723T1020T2600T3011T4431Work210Workvarmış gibi: Avail (2 1 0), Need₀ (7 2 3)

Varmış gibi: Available = (2 1 0). Hangi Need ≤ (2 1 0)? T1 (0 2 0): B yetmez; T3 (0 1 1): C yetmez…

AllocationABCT0030T1302T2302T3211T4002NeedABCT0723T1020T2600T3011T4431Work210WorkSıra: —hiçbir satır uymuyor → GÜVENSİZ → REDDET

Hiçbir süreç bitirilemiyor: durum güvensiz. Değişiklikler geri alınır, T0 bekletilir; kaynak boşta olduğu hâlde.

Kaçınma

Çoklu Kaynak: İkinci Örnek

AtanmışTpPlYzCDA3011B0100C1110D1101E0000Hâlâ gerekenTpPlYzCDA1100B0112C3100D0010E2110E = (6 3 4 2)P = (5 3 2 2)A = (1 0 2 0)E = var olan, P = atanmış toplamı, A = E − P (boşta)

Beş süreç, dört kaynak türü (Tp, Pl, Yz=yazıcı, CD). A = E − P = (1 0 2 0).

AtanmışTpPlYzCDA3011B0100C1110D1101E0000Hâlâ gerekenTpPlYzCDA1100B0112C3100D0010E2110E = (6 3 4 2)P = (5 3 2 2)A = (1 0 2 0)güvenli dizi: D, E, A, B, C

D (0 0 1 0) ≤ A → biter, A = (2 1 2 1); E, A, B, C de sırayla biter. Durum güvenli.

AtanmışTpPlYzCDA3011B0110C1110D1101E0000Hâlâ gerekenTpPlYzCDA1100B0102C3100D0010E2110E = (6 3 4 2)P = (5 3 2 2)A = (1 0 1 0)B bir yazıcı ister → A = (1 0 1 0), dizi D, E, A, B, C hâlâ var → VER

B bir yazıcı ister. Verilirse A = (1 0 1 0); D yine bitebilir ve dizi korunur: verilir.

AtanmışTpPlYzCDA3011B0110C1110D1101E0010Hâlâ gerekenTpPlYzCDA1100B0102C3100D0010E2100E = (6 3 4 2)P = (5 3 2 2)A = (1 0 0 0)sonra E son yazıcıyı ister → A = (1 0 0 0), kimse bitemez → ERTELE

Ardından E son yazıcıyı isterse A = (1 0 0 0) olur ve hiçbir satır karşılanamaz: güvensiz → ertelenir.

Tanenbaum MOS Şekil 6-12. Eski sunumdaki “her satırda ≤ A olan satırı ara” adımları burada güvenlik testidir; aynı mantık tespit algoritmasında istek matrisiyle, kaçınmada kalan ihtiyaç matrisiyle kullanılır.

Kaçınma

Bankacı Algoritması Pratikte

Varsayımlar

Her süreç azami ihtiyacını önceden bildirir; süreç sayısı sabittir; kaynak sayısı değişmez (aygıt bozulmaz); süreçler kaynakları sonlu sürede bırakır.

Gerçek sistemler

Bu varsayımlar genel amaçlı İS'lerde tutmaz; algoritma neredeyse hiç kullanılmaz. Benzer “kabul denetimi” fikri: gerçek zamanlı zamanlama, bulut kotaları, havuzlu bağlantı limitleri.

  • Eski sunumda kaçınma “tespit ya da kurtarmadan daha verimli” olarak anılıyordu: her istekte O(m·n²) test ve gereksiz ertelemeler nedeniyle genellikle daha pahalıdır; avantajı kurtarma gerektirmemesidir.
  • “Algoritma arka planda sürekli çalışır” ifadesi de yanlıştı: test yalnızca bir istek geldiğinde (ve bir kaynak bırakıldığında bekleyenler için) yapılır.
Kendi değerlerinizle deneyin: Kilitlenme ve Bankacı Algoritması Simülatörü: Allocation, Max, Need, Available girip güvenli diziyi ve istek kontrolünü adım adım izleyin.

Önleme

Önleme: Koşullara Saldırmak

KoşulSaldırıBedeli
Karşılıklı dışlamaKaynağı paylaşılabilir yap: biriktirme (spooling), salt okunur paylaşım, kilitsiz yapılarÇoğu kaynak doğası gereği paylaşılamaz (mutex!)
Tut ve bekleTüm kaynakları başta tek seferde iste; ya da yeni istekten önce elindekileri bırakDüşük kullanım, açlık; ihtiyaç önceden bilinmeli
Kesme yokBekleyecek sürecin kaynaklarını geri al; tryLock + geri çekil; sanallaştırYalnızca durumu kaydedilebilen kaynaklarda; canlı kilit riski
Döngüsel beklemeKaynaklara toplam sıra ver, yalnızca artan sırada iste (kilit sıralaması)Sıraya uymak programcı disiplini ister
Eski sunumdaki iki ifade düzeltildi: karşılıklı dışlamayı kaldırmak “her seferinde yalnızca bir süreç kaynak isteyebilir” demek değildir (bu dışlamanın kendisidir). “Kesme yok” koşulunu kaldırmak da “süreç bitene kadar kaynakları tutsun” değil, tersine kaynakların geri alınabilmesidir.

Önleme

Karşılıklı Dışlamaya Saldırı

  • Biriktirme (spooling): süreçler çıktıyı diske yazar; yazıcıyı tek bir daemon sırayla kullanır. Yazıcı için çekişme kalkar.
  • Salt okunur dosyalar ve kod sayfaları aynı anda paylaşılır; okur kilitleri birbirini dışlamaz.
  • Kilitsiz (lock-free) yapılar CAS ile ilerler; kilit olmadığı için kilitlenme de olmaz (açlık hâlâ mümkün).
  • Sınır: biriktirme diski de bir kaynaktır. Disk, yarım kalmış çıktılarla dolarsa yine kilitlenme olabilir (Tanenbaum).
  • Genel ilke: bir kaynağı gerçekten gerekmedikçe atama, onu isteyecek süreç sayısını en aza indir.
P1P2P3spooldizinilpdyazıcıtek sahipYazıcıyı yalnızca daemon tutar:kullanıcı süreçleri onu hiç beklemez

Önleme

Tut ve Beklemeye Saldırı

  • Protokol 1: süreç ihtiyaç duyacağı tüm kaynakları çalışmaya başlamadan önce tek bir istekte alır (hepsi ya da hiçbiri).
  • Protokol 2: süreç yalnızca elinde hiçbir kaynak yokken istek yapabilir: yenisini istemeden önce tuttuklarını bırakır.
  • Örnek: DVD → disk kopyala, diski sırala, yazıcıya bas. Protokol 1'de yazıcı en baştan sona kadar boşa tutulur.
  • Sorunlar: düşük kaynak kullanımı; çok kaynak isteyen süreç için açlık; ihtiyaçlar çoğu zaman önceden bilinmez.
  • Pratikte: pthread_mutex_trylock ile “ya hepsi ya hiçbiri” edinimi; veritabanlarında tüm kilitleri baştan alan muhafazakâr 2PL.
1) Başta hepsini isteDVDDiskYazıcı2) Önce bırak, sonra isteDVDDiskDiskYazıcıkullanımboşa tutma

Silberschatz 10e §8.5.2.

Önleme

Kesme Yok Koşuluna Saldırı

  • Geri alma protokolü: kaynak tutan bir süreç hemen karşılanamayan bir istek yaparsa, tuttuğu tüm kaynaklar örtük olarak bırakılır; süreç hepsini birlikte alabildiğinde yeniden başlar.
  • Yalnızca durumu kaydedilip geri yüklenebilen kaynaklara uygundur: CPU yazmaçları, bellek, veritabanı işlemi (abort).
  • Sanallaştırma: yazıcı biriktirilir, bellek sayfalanır.
  • Mutex için: zaman aşımlı deneme. Edinemeyen iş parçacığı elindekini kendisi bırakır ve rastgele bir süre sonra yeniden dener.
  • Çalıştırıldı (JDK 21): 2 iş parçacığı × 1000 ters yönlü transfer, sonuç x=1000 y=1000 toplam=2000.
boolean dene(Hesap k, Hesap h, int m)
        throws InterruptedException {
  if (!k.kilit.tryLock(50, MILLISECONDS))
    return false;
  try {
    if (!h.kilit.tryLock(50, MILLISECONDS))
      return false;  /* k'yi de bırak */
    try { k.bakiye -= m; h.bakiye += m;
          return true; }
    finally { h.kilit.unlock(); }
  } finally { k.kilit.unlock(); }
}
/* çağıran: while (!dene(x, y, 1))
              Thread.sleep(rastgele); */

Rastgele bekleme önemli: iki iş parçacığı aynı ritimde dener-bırakırsa canlı kilit oluşur (ileride).

Önleme

Döngüsel Beklemeye Saldırı

#Kaynak
1Görüntüleyici
2Yazıcı
3Çizici
4Teyp sürücü
5Blu-ray sürücü

Yazıcı ve teyp gerekiyorsa önce 2, sonra 4 istenir. Uygun bir sıralamayı bulmak en zor kısımdır.

ABij

Her kaynak türüne bir numara verilir. Kural: süreç yalnızca elindekilerden büyük numaralı kaynak isteyebilir.

ABijA: i'yi tutuyor, j'yi istiyor → i < j

A, i'yi tutup j'yi istiyorsa kurala göre i < j.

ABijB: j'yi tutuyor, i'yi istiyor → j < i ?i < j ve j < i olamaz: çelişki

B, j'yi tutup i'yi isterse j < i olmalı: çelişki. Bu kenar hiç oluşamaz. Genel olarak döngüdeki en büyük numaralı kaynağı tutan süreç daha büyüğünü isteyemez.

Tanenbaum MOS Şekil 6-13. Varyant: süreç Kj'yi isteyecekse elindeki tüm Ki (i ≥ j) kaynaklarını önce bırakmalıdır.

Önleme · Kodu adım adım çalıştır

Kilit Sıralaması Pratikte

void transfer(Hesap k, Hesap h, int m) {
  Hesap ilk = k.id < h.id ? k : h;
  Hesap ikinci = k.id < h.id ? h : k;
  ilk.kilit.lock();
  try {
    ikinci.kilit.lock();
    try { k.bakiye -= m; h.bakiye += m; }
    finally { ikinci.kilit.unlock(); }
  } finally { ilk.kilit.unlock(); }
}
/* T1: transfer(x, y, 1)   x.id = 1
   T2: transfer(y, x, 1)   y.id = 2 */
T1T2xyid 1id 2

T1 x→y, T2 y→x aktarıyor: “doğal” sıra iki iş parçacığında terstir. Kilitlerin id sırası ise ortaktır.

T1T2xyid 1id 2

T1: ilk = x (1 < 2). x kilidini alır.

T1T2xyid 1id 2

T2: k = y ama ilk yine x (id 1). x'i bekler; elinde hiçbir kilit yok.

T1T2xyid 1id 2

T1 y'yi de alır (kimse tutmuyor) ve aktarımı yapar.

T1T2xyid 1id 2

T1 kilitleri bırakır; T2 x'i, sonra y'yi alır. Döngü oluşamaz.

T1T2xyid 1id 2

Çalıştırıldı (JDK 21): her biri 100 000 ters yönlü aktarım, sonuç x=1000 y=1000, kilitlenme yok.

Linux çekirdeği aynı türden iki kilidi adres sırasıyla alır (ör. double_rq_lock); kilit sırası belgelenir ve lockdep ile denetlenir.

Diğer Sorunlar

İki Aşamalı Kilitleme (2PL)

  • Veritabanı işlemleri için protokol: büyüme evresinde yalnızca kilit alınır, küçülme evresinde yalnızca bırakılır; ilk bırakıştan sonra yeni kilit alınamaz.
  • Amacı serileştirilebilirliktir (işlemler sanki sırayla çalışmış gibi), kilitlenmeyi önlemek değil. Düz 2PL kilitlenebilir: T1 a'yı, T2 b'yi kilitler; sonra çapraz isterler.
  • Tanenbaum'un varyantı: 1. evrede tüm kayıtları kilitlemeyi dene; biri kilitliyse hepsini bırak ve baştan başla. Bu, tut ve beklemeyi kaldırır.
  • Katı (strict) 2PL: kilitler işlem sonunda (commit/abort) bırakılır. Kilitlenmeleri DBMS bekleme çizgesiyle tespit edip bir işlemi geri sarar.
zamantutulan kilitkilit noktasıbüyümeküçülme
Eski sunumda 2PL “yalnızca gerektiğinde kilit al, en kısa sürede bırak” ve “İS'de kilitlenmeyi önleyen protokol” olarak tanımlanıyordu; ikisi de yanlış.

Diğer Sorunlar

İletişim Kilitlenmeleri

  • İletişim kilitlenmesi: kaynak yoktur, süreçler birbirinden mesaj bekler. A, B'ye istek gönderip yanıt bekler; istek kaybolursa A yanıtı, B isteği sonsuza dek bekler.
  • Kaynak sıralaması ya da kaçınma işe yaramaz; çözüm zaman aşımı (timeout) ve yeniden gönderme. Yinelenen mesajlar için protokolde sıra numarası gerekir.
  • Ağ donanımında ise tamponlar gerçek kaynaktır; aşağıdaki halka bir kaynak kilitlenmesidir.
ABCD

Dört yönlendirici halka biçiminde; her birinin sınırlı tampon belleği var.

ABCDher tampon dolu;paketler bir sonrakine gidecek

Yoğun trafikte tüm tamponlar, saat yönünde bir sonraki yönlendiriciye gidecek paketlerle dolar.

ABCDher tampon dolu;paketler bir sonrakine gidecekkimse gönderemez: kaynak kilitlenmesi

A, B'nin boş tamponunu bekler; B, C'nin; C, D'nin; D, A'nın: döngüsel bekleme. Çözüm: zaman aşımıyla paket düşürme, sanal kanallar, kredi tabanlı akış denetimi.

Tanenbaum MOS §6.7.2, Şekil 6-15.

Diğer Sorunlar

Canlı Kilit (Livelock)

  • Koridorda karşılaşan iki kişi aynı anda aynı yana kayar: kimse geçemez.
  • Kilitlenmede süreçler uyur; canlı kilitte çalışır ama faydalı iş yapmaz.
void process_A(void) {
  enter_region(&resource_1);
  enter_region(&resource_2);
  use_both_resources();
  leave_region(&resource_2);
  leave_region(&resource_1);
}  /* B: önce resource_2, sonra 1 */

Tanenbaum Şekil 6-16: meşgul beklemeli enter_region ters sırada çağrılırsa süreçler bloke olmadan sonsuza dek döner.

ABzamanr1 alr2 ✗r2 alr1 ✗ikisi de bırakır

A r1'i, B r2'yi alır. A r2'yi dener (tryLock başarısız), B r1'i dener (başarısız).

ABzamanr1 alr2 ✗r2 alr1 ✗ikisi de bırakırr1 alr2 ✗r2 alr1 ✗ikisi de bırakır

Kibar davranırlar: ikisi de elindekini bırakır ve aynı süre sonra yeniden dener. Aynı şey tekrarlanır.

ABzamanr1 alr2 ✗r2 alr1 ✗ikisi de bırakırr1 alr2 ✗r2 alr1 ✗ikisi de bırakırr1 alr2 ✗r2 alr1 ✗ikisi de bırakırdurum değişiyor, iş ilerlemiyor

Süreçler bloke değil, CPU harcıyor, durumları sürekli değişiyor; ama hiçbiri ilerlemiyor: canlı kilit.

ABzamanr1 alr2 ✗r2 alr1 ✗ikisi de bırakırr1 alr2 ✗r2 alr1 ✗ikisi de bırakırr1 alr2 ✗r2 alr1 ✗ikisi de bırakırr1, r2 ✓bekler2, r1 ✓rastgele geri çekilme: ritim bozulur

Çözüm: rastgele (üstel) geri çekilme, öncelik/sıra numarası ya da kilit sıralaması. Ethernet'in CSMA/CD geri çekilmesi aynı fikirdir.

Diğer Sorunlar

Açlık (Starvation)

  • Bir süreç, kaynak kullanılabilir olduğu hâlde ona hiç sıra gelmediği için süresiz bekler. Diğerleri ilerler: sistem kilitlenmemiştir.
  • Kaynak dağıtım politikasının sonucudur. Örnek: yazıcıyı her seferinde en küçük dosyaya vermek ortalama bekleme süresini azaltır ama büyük dosyayı aç bırakabilir.
  • Başka örnekler: katı öncelikli zamanlama, okur öncelikli okur-yazar kilidi, kurtarmada hep aynı kurbanın seçilmesi.
  • Çözüm: ilk gelen ilk hizmet alır (FIFO) ya da bekledikçe önceliği artırma (yaşlandırma).
yazıcıyeni küçük işler sürekli geliyorbüyük iş100 MBbekliyor… bekliyor…çözüm: FIFO ya da yaşlandırma (aging)
KilitlenmeCanlı kilitAçlık
Süreç durumublokeçalışıyorhazır/bloke
Kim etkilenir?döngüdeki herkesetkileşen grupbir ya da birkaç süreç

Pratikte Kilitlenme · Kodu adım adım çalıştır

Java'da Kilitlenme

Object a = new Object(), b = new Object();

Thread t1 = new Thread(() -> {
  synchronized (a) {
    uyu(10);   /* pencereyi büyüt */
    synchronized (b) { isle(); }
  }
}, "T1");
Thread t2 = new Thread(() -> {
  synchronized (b) {
    uyu(10);
    synchronized (a) { isle(); }
  }
}, "T2");
t1.start(); t2.start();
T1T2ab

İki iş parçacığı iki monitörü (synchronized kilidi) ters sırada alacak.

T1T2ab

T1 a'nın monitörüne girer ve uyur.

T1T2ab

Bu sırada T2 b'nin monitörüne girer.

T1T2ab

T1 uyanır, b'yi ister: b T2'de → T1 BLOCKED.

T1T2abBLOCKED: döngü

T2 a'yı ister → BLOCKED. JVM monitörleri kesilemez: program asla bitmez.

uyu(10) zamanlamayı çok olası kılar ama garanti etmez. CountDownLatch ile iki ilk kilit alınana dek bekletilen sürüm JDK 21'de her çalıştırmada kilitlendi.

Pratikte Kilitlenme

Kilitlenmeyi Bulmak: jstack

$ jstack <pid>
Found one Java-level deadlock:
=============================
"T1":
  waiting to lock monitor 0x… (object 0x…, a java.lang.Object),
  which is held by "T2"
"T2":
  waiting to lock monitor 0x… (object 0x…, a java.lang.Object),
  which is held by "T1"

Java stack information for the threads listed above:
"T1":
        at Asili.calis(Asili.java:7)
        - waiting to lock <0x…d0> (a java.lang.Object)
        - locked <0x…c0> (a java.lang.Object)
…
Found 1 deadlock.

JDK 21'de gerçek çıktı (adresler kısaltıldı). Aynı rapor: jcmd <pid> Thread.print, JConsole/VisualVM “Detect Deadlock”.

ThreadMXBean mx = ManagementFactory.getThreadMXBean();
long[] ids = mx.findDeadlockedThreads();
if (ids != null)
  for (ThreadInfo ti : mx.getThreadInfo(ids))
    System.out.println(ti.getThreadName()
      + " bekliyor, kilit sahibi " + ti.getLockOwnerName());
T1 bekliyor, kilit sahibi T2
T2 bekliyor, kilit sahibi T1
  • JVM, monitör ve ReentrantLock sahipliğinden bekleme çizgesi kurup döngü arar.
  • Tespit eder ama kurtarmaz: süreci yeniden başlatmak gerekir.

Pratikte Kilitlenme

Araçlar: lockdep ve Diğerleri

OrtamAraç / davranış
Linux çekirdeğilockdep (CONFIG_PROVE_LOCKING): kilit sırası doğrulayıcı; hung task dedektörü
C/C++ThreadSanitizer: lock-order-inversion; Valgrind Helgrind
Javajstack, jcmd, ThreadMXBean
Gofatal error: all goroutines are asleep - deadlock!
VeritabanıPostgreSQL, InnoDB: bekleme çizgesi + kurban işlemi geri sarma
mmap_locki_rwsem

lockdep her kilidi bir sınıfa (aynı türdeki tüm örnekler) bağlar.

mmap_locki_rwsemyol 1: A sonra B

Bir görev A'yı tutarken B'yi alınca “A → B” kenarı kaydedilir.

mmap_locki_rwsemyol 1: A sonra Byol 2: B sonra A (başka zaman)possible circular locking dependency

Başka bir yolda B tutulurken A alınırsa çizgede döngü oluşur: kilitlenme hiç yaşanmadan rapor edilir.

lockdep ve TSan potansiyel kilitlenmeyi bulur (sıra ihlali); jstack ve Go çalışma zamanı ise gerçekleşmiş kilitlenmeyi raporlar.

Özet

Özet

YaklaşımNe zaman?Bilgi gereksinimiBedelKullanım
Görmezden gel—yokara sıra yeniden başlatmagenel amaçlı İS
Tespit + kurtarmasonraşu anki tahsis ve isteklerperiyodik O(m·n²), kayıp işveritabanları, JVM araçları
Kaçınmaher istekteazami ihtiyaçlar (Max)ertelemeler, O(m·n²)/isteknadiren, özel sistemler
Önlemetasarımdakaynak sırasıesneklik ve kullanım kaybıçekirdek, uygulama kodu
  • Dört koşul birlikte gereklidir; tek örnekli kaynaklarda döngü ⇔ kilitlenme.
  • Güvensiz durum kilitlenme değildir ama bitiş garantisi yoktur.
  • Pratikte en etkili araç: kilit sıralaması + zaman aşımlı deneme + araçlarla (lockdep, jstack, TSan) denetim.

Özet

Kontrol Soruları

  1. Kilitlenmenin dört koşulunu yazın. Hangisi bir politika değil, durumdur?
  2. Çizgede döngü varken kilitlenme olmaması nasıl mümkündür? Örnek verin.
  3. E = (4 2 3 1), A = (2 1 0 0) örneğinde P3'ün isteği (2 1 0 1) olsaydı sonuç ne olurdu?
  4. Güvensiz durum ile kilitlenmiş durum arasındaki fark nedir?
  5. Silberschatz örneğinde T1'in (1 0 2) isteğinden sonra T0 (0 2 0) isterse ne olur? Neden?
  6. Bankacı algoritması genel amaçlı İS'lerde neden kullanılmaz?
  7. Kaynak numaralandırma döngüsel beklemeyi neden imkânsız kılar?
  8. Canlı kilit ile kilitlenme arasındaki fark nedir? Canlı kilit nasıl kırılır?
Cevaplar
  1. Karşılıklı dışlama, tut ve bekle, kesme yok, döngüsel bekleme; döngüsel bekleme o anki durumdur.
  2. Çok örnekli kaynakta döngü dışındaki bir süreç örneğini bırakabilir (Silberschatz Şekil 8.6: T4, R2'yi bırakır).
  3. Hiçbir satır ≤ A olmaz; P1, P2, P3 kilitlenmiştir.
  4. Güvensizde henüz kimse kalıcı olarak bloke değildir ama herkesin bitmesi garanti edilemez; kilitlenmede döngü oluşmuştur.
  5. Kaynak boşta olsa da varmış gibi durumda Available = (2 1 0) ve hiçbir Need karşılanamaz: güvensiz, T0 bekletilir.
  6. Azami ihtiyaçlar önceden bilinmez, süreç ve kaynak sayısı değişir, her istekteki test pahalıdır.
  7. Döngüdeki en büyük numaralı kaynağı tutan süreç daha küçük numaralı bir kaynak isteyemez; döngü kapanamaz.
  8. Kilitlenmede süreçler bloke, canlı kilitte çalışıyor ama ilerlemiyor; rastgele geri çekilme ya da sıralama ile kırılır.

Özet

Kaynaklar

  • A. Silberschatz, P. B. Galvin, G. Gagne, Operating System Concepts, 10. baskı, Wiley, 2018 — Bölüm 8: Deadlocks.
  • A. S. Tanenbaum, H. Bos, Modern Operating Systems, 4. baskı (2014) / 5. baskı (2022), Pearson — Bölüm 6: Deadlocks.
  • R. H. Arpaci-Dusseau, A. C. Arpaci-Dusseau, Operating Systems: Three Easy Pieces (OSTEP), ostep.org — “Common Concurrency Problems”.
  • E. G. Coffman, M. J. Elphick, A. Shoshani, “System Deadlocks”, ACM Computing Surveys 3(2), 1971.
  • E. W. Dijkstra, “Cooperating Sequential Processes”, EWD-123, 1965 (Bankacı algoritması); R. C. Holt, “Some Deadlock Properties of Computer Systems”, ACM Computing Surveys, 1972.
  • Linux çekirdek belgeleri: Documentation/locking/lockdep-design.rst.
  • Java SE 21: java.lang.management.ThreadMXBean, java.util.concurrent.locks.ReentrantLock; jstack kılavuzu.
  • PostgreSQL belgeleri: “Explicit Locking — Deadlocks”, deadlock_timeout.

Son

Bölüm 7: Kilitlenme
Sonraki bölüm: Bellek Yönetimi
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.