Kilitlenme nedir?


Yanıtlar:


207

Birden fazla işlem aynı kaynağa aynı anda erişmeye çalıştığında bir kilit oluşur.

Bir işlem kaybedilir ve diğerinin bitmesini beklemek gerekir.

Bir kilitlenme bekleme süreci hala kendinden önceki ilk ihtiyaçlarını bitirmek anlamına başka bir kaynak tutan yok ki oluşur.

Yani, bir örnek:

Kaynak A ve kaynak B, süreç X ve süreç Y tarafından kullanılır

  • X, A'yı kullanmaya başlar.
  • X ve Y, B kullanmaya başlamaya çalışır
  • Y 'kazanır' ve önce B olur
  • şimdi Y'nin A kullanması gerekiyor
  • A, Y tarafından bekleyen X tarafından kilitlenir

Kilitlenmeleri önlemenin en iyi yolu, süreçlerin bu şekilde geçmesini önlemektir. Bir şeyi olabildiğince kilitleme ihtiyacını azaltın.

Veritabanlarında, tek bir işlemde farklı tablolarda çok fazla değişiklik yapmaktan kaçının, tetikleyicilerden kaçının ve mümkün olduğunca iyimser / kirli / nolock okumalarına geçin.


9
Buradaki işlemi genelleştirme olarak kullanıyorum, özellikle bir OS Süreci değil. Bunlar iş parçacıkları olabilir, ancak tamamen farklı uygulamalar veya veritabanı bağlantıları da olabilir. Desen aynı.
Keith

1
Merhaba, bu senaryo göz önüne alındığında: İş parçacığı A kaynak A kilitler ve uzun bir süreç var. İş parçacığı B kaynak kilitlemek için bekliyor A. CPU zaman kullanımı:% 20, bir kilitlenme durumu olduğunu düşünebilir misiniz?
rickyProgrammer

2
@rickyProgrammer hayır, fark biraz akademik olsa da, bu sadece düzenli bir kilit beklemesi. B yavaş A'yı beklemek bir kilittir, B B'yi beklemek bir B kilitlenmedir.
Keith

Yani kilitlenme kaynakların serbest bırakılmasını bekleyen kilitli kaynaklara sahip iki süreçten daha fazlası ..
rickyProgrammer

2
@rickyProgrammer, dairesel kuyruk nedeniyle ne kadar beklediğiniz önemli değil, özgür olmayacak bir kilit.
Keith

126

Suç filmlerinden çıkmaza girme durumu için gerçek bir dünyayı (aslında gerçek olmayan) açıklayayım. Bir suçlunun rehin aldığını ve buna karşı bir polisin de suçlunun dostu olan bir rehinesi olduğunu düşünün. Bu durumda, polis arkadaşının gitmesine izin vermezse suçlu rehineye gitmeyecek. Ayrıca polis, suçlu rehineyi serbest bırakmadıkça, suçlu arkadaşının gitmesine izin vermeyecektir. Bu sonsuz bir güvenilmez durumdur, çünkü her iki taraf da ilk adımın birbirinden ısrar ediyor.

Ceza ve Polis Sahnesi

resim açıklamasını buraya girin

Yani, basitçe, iki iş parçacığının iki farklı kaynağa ihtiyacı olduğunda ve her birinin diğer ihtiyaç duyduğu kaynağın kilidine sahip olması, bir çıkmazdır.

Kilitlenmenin Bir Başka Yüksek Seviyesi Açıklaması: Kırık Kalpler

Bir kızla çıkıyorsunuz ve bir tartışmadan bir gün sonra, her iki taraf da birbirinize kalp kırıyor ve özür dilerim ve özlediğim bir çağrı bekliyorum. Bu durumda, her iki taraf da yalnızca bir tanesi diğerinden üzgünüm çağrısı alırsa birbirleriyle iletişim kurmak ister . Her ikisinin de iletişim kurmayacağı ve pasif bir durumda beklemeyeceği için, her ikisi de diğerinin kilitlenme durumu ile sonuçlanan iletişime başlamasını bekleyecektir.


İş parçacıkları farklı işlemlere ait midir? Aynı işleme ait iş parçacıkları da bir kilitlenmeye neden olabilir mi?
lordvcs

1
@diabolicfreak İpliklerin aynı sürece ait olup olmaması önemli değildir.
Sam Malayek

2
Gerçek hayattan başka bir örnek, aynı anda dört yönde iki eşit yolun kesiştiği dört araba olabilir. Herkesin sağ taraftan bir araca bir yol vermesi gerekir, böylece kimse ilerleyemez.
LoBo

35

Kilitlenmeler sadece aynı anda alınabilecek iki veya daha fazla kilit olduğunda ve farklı sırayla yakalandığında ortaya çıkar.

Kilitlenmeden kaçınmanın yolları:

  • kilitleri kullanmaktan kaçının (mümkünse),
  • birden fazla kilit kullanmaktan kaçının
  • kilitleri daima aynı sırayla alınız.

Bir kilitlenmeyi önlemek için 3. nokta (her zaman kilitleri aynı sırayla alın) hayati önem taşır, bu da kodlama uygulamasında unutulması oldukça kolaydır.
Qiang Xu

20

Kilitlenmeyi tanımlamak için önce süreci tanımlarım.

Süreç : Bildiğimiz gibi süreç bir programicradan başka bir şey değildir .

Kaynak : Bir program işlemini yürütmek için bazı kaynaklara ihtiyaç vardır. Kaynak kategorileri arasında bellek, yazıcılar, CPU'lar, açık dosyalar, manyetik bant sürücüleri, CD-ROM'lar vb. Bulunabilir.

Kilitlenme : Kilitlenme, iki veya daha fazla işlemin bazı kaynakları tuttuğu ve daha fazla kaynak edinmeye çalıştığı bir durum veya durumdur ve buradaki işlemleri tamamlayana kadar kaynakları serbest bırakamazlar.

Kilitlenme durumu veya durumu

resim açıklamasını buraya girin

Yukarıdaki şemada iki P1 ve p2 işlemi vardır ve iki R1 ve R2 kaynağı vardır .

Kaynak R1 , proses P1'e ve kaynak R2 , proses p2'ye tahsis edilir . İşlem P1'in yürütülmesini tamamlamak için R2 kaynağına ihtiyaç vardır , bu nedenle R2 için P1 talebi , ancak R2 zaten P2'ye tahsis edilmiştir .

Aynı şekilde , işleminin tamamlanması için P2 İşleminin R1'e ihtiyacı vardır , ancak R1 zaten P1'e tahsis edilmiştir .

her iki süreç de yürütme işlemlerini tamamlayana kadar ve kaynaklarını serbest bırakamazlar. Yani her ikisi de başka bir kaynak bekliyor ve sonsuza dek bekleyecekler. Yani bu bir DEADLOCK Koşulu.

Kilitlenmenin meydana gelmesi için dört koşul doğru olmalıdır.

  1. Karşılıklı hariç tutma - Her kaynak şu anda tam olarak bir işleme ayrılmıştır veya kullanılabilir. (İki süreç aynı kaynağı aynı anda kontrol edemez veya kritik bölümlerinde olamaz).
  2. Beklet ve Bekle - şu anda kaynakları elinde tutan işlemler yeni kaynaklar isteyebilir.
  3. Önlem yok - Bir işlem bir kaynağı tuttuğunda, başka bir işlem veya çekirdek tarafından kaldırılamaz.
  4. Dairesel bekleme - Her işlem başka bir işlem tarafından tutulan bir kaynak elde etmeyi bekliyor.

ve tüm bu koşullar yukarıdaki şemada karşılanmıştır.


8

Bir iş parçacığı hiçbir zaman gerçekleşmeyen bir şeyi beklerken bir kilitlenme oluşur.

Tipik olarak, bir iş parçacığı, önceki sahibi tarafından asla serbest bırakılmayan bir muteks veya semaforda beklerken olur.

Ayrıca, iki iş parçacığı ve iki kilit içeren bir durum olduğunda da sık sık olur:

Thread 1               Thread 2

Lock1->Lock();         Lock2->Lock();
WaitForLock2();        WaitForLock1();   <-- Oops!

Genellikle onları algılarsınız çünkü gerçekleşmesini beklediğiniz şeyler asla gerçekleşmez veya uygulama tamamen askıda kalır.


Bir iş parçacığı şey bekliyor BIR kilitlenme olur edemez ortaya çıkar.
Lorne Marquis

4

Bu harika makalelere Deadlock bölümünden bakabilirsiniz . C # 'da ama fikir hala diğer platformlar için aynı. Burada kolay okuma için alıntı yapıyorum

İki iş parçacığı diğeri tarafından tutulan bir kaynak beklediğinde bir kilitlenme oluşur, bu nedenle de devam edemez. Bunu göstermenin en kolay yolu iki kilittir:

object locker1 = new object();
object locker2 = new object();

new Thread (() => {
                    lock (locker1)
                    {
                      Thread.Sleep (1000);
                      lock (locker2);      // Deadlock
                    }
                  }).Start();
lock (locker2)
{
  Thread.Sleep (1000);
  lock (locker1);                          // Deadlock
}

4

Kilitlenme, işletim sistemindeki çoklu işleme / çoklu programlama sorunlarında yaygın bir sorundur. Diyelim ki iki süreç P1, P2 ve iki global paylaşılabilir kaynak R1, R2 ve kritik bölümde her iki kaynağa da erişilmesi gerekiyor

Başlangıçta, OS P1'i işlemek için R1'i ve P2'yi işlemek için R2'yi atar. Her iki işlem de eşzamanlı olarak çalıştığından kodlarını yürütmeye başlayabilirler ancak SORUN bir işlem kritik bölüme çarptığında ortaya çıkar. Bu yüzden R1 işlemi P2 işleminin R2'yi serbest bırakmasını bekleyecek ve tersi de ... Sonsuza dek bekleyecekler (DEADLOCK CONDITION).

Küçük bir ANALOGİ ...

Anneniz (OS),
Siz (P1),
Kardeşiniz (P2),
Elma (R1),
Bıçak (R2),
kritik bölüm (elmayı bıçakla kesme).

Annen başlangıçta sana elma ve bıçağı kardeşine verir.
Her ikisi de mutlu ve oynuyor (Kodlarını yürütmek).
Biriniz elmayı (kritik bölüm) bir noktada kesmek istiyor.
Elmayı kardeşine vermek istemiyorsun.
Kardeşin bıçağı sana vermek istemiyor.
Yani ikiniz de çok uzun bir süre bekleyeceksiniz :)


2

Kilitlenme, iki dişin her ikisinin de ilerlemesini engelleyen kilitleri ortaya çıkardığında oluşur. Onlardan kaçınmanın en iyi yolu dikkatli gelişimdir. Birçok gömülü sistem, bir bekçi zamanlayıcısı (belirli bir süre askıda kaldığında sistemi sıfırlayan bir zamanlayıcı) kullanarak bunlara karşı koruma sağlar.


2

Her biri kilitli bir kaynağı tutan ve zincirdeki bir sonraki eleman tarafından tutulan bir kaynağı kilitlemeye çalışan dairesel bir iş parçacığı veya süreç zinciri olduğunda bir kilitlenme oluşur. Örneğin, sırasıyla A ve B kilitlerini tutan ve her ikisi de diğer kilidi almaya çalışan iki iş parçacığı.


Sana oy veriyorum. Cevabınız yukarıda olduğundan daha özlüdür, çünkü süreç ya da iş parçacığı tarafından meydana gelen karışıklığı meydana getirir. Bazıları süreç demek, bazıları konu demek :)
hainguyen

1

Deadlock durumunu anlamak için klasik ve çok basit bir program : -

public class Lazy {

    private static boolean initialized = false;

    static {
        Thread t = new Thread(new Runnable() {
            public void run() {
                initialized = true;
            }
        });

        t.start();

        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println(initialized);
    }
}

Ana iş parçacığı Lazy.main'i çağırdığında, Lazy sınıfının başlatılıp başlatılmadığını denetler ve sınıfı başlatmaya başlar. Ana iş parçacığı artık false olarak ayarlanmış olarak ayarlanmış, çalışma yöntemi kümeleri true olarak ayarlanmış bir arka plan iş parçacığı oluşturur ve başlatır ve arka plan iş parçacığının tamamlanmasını bekler.

Bu kez, sınıf şu anda başka bir iş parçacığı tarafından başlatılıyor. Bu koşullar altında, arka plan iş parçacığı olan geçerli iş parçacığı, başlatma işlemi tamamlanana kadar Class nesnesinde bekler. Ne yazık ki, başlatmayı yapan iş parçacığı olan ana iş parçacığı, arka plan iş parçacığının tamamlanmasını bekliyor. İki iş parçacığı artık birbirini beklediğinden, program DEADLOCKED.


0

Kilitlenme, hiçbir işlemin / iş parçacığının bir eylem gerçekleştiremediği bir sistem durumudur. Başkaları tarafından belirtildiği gibi, bir kilitlenme, tipik olarak her işlemin / iş parçacığının, başka (veya aynı) bir işlem / iş parçacığı tarafından zaten kilitlenmiş olan bir kaynağa kilit almak istediği durumun sonucudur.

Onları bulmak ve önlemek için çeşitli yöntemler vardır. Biri çok düşünmek ve / veya çok şey denemek. Bununla birlikte, paralellikle uğraşmak herkesin bildiği gibi zordur ve çoğu (hepsi olmasa da) insanların problemlerden tamamen kaçınamayacaklarıdır.

Bu tür sorunlarla başa çıkmak konusunda ciddiyseniz, bazı daha resmi yöntemler yararlı olabilir. Farkına vardığım en pratik yöntem süreç teorik yaklaşımını kullanmaktır. Burada sisteminizi bazı işlem dillerinde (örn. CCS, CSP, ACP, mCRL2, LOTOS) modelleyebilir ve kilitlenmeleri (ve belki de bazı diğer özellikleri) kontrol etmek için (model-) kullanılabilir araçları kullanabilirsiniz. Kullanılacak araç seti örnekleri FDR, mCRL2, CADP ve Uppaal'dir. Bazı cesur ruhlar, tamamen sembolik yöntemler (teorem kanıtlama; Owicki-Gries'i arayın) kullanarak sistemlerinin kilitlenmesini bile kanıtlayabilir.

Bununla birlikte, bu biçimsel yöntemler tipik olarak biraz çaba gerektirir (örneğin, süreç teorisinin temellerini öğrenmek). Ama sanırım bu sadece bu sorunların zor olmasının bir sonucu.


0

Kilitlenme, farklı işlem tarafından talep edildiği için kullanılabilir kaynak sayısının az olması durumunda ortaya çıkan bir durumdur. Bu, mevcut kaynakların sayısı kullanıcı tarafından talep edilenden daha az olduğunda, o zaman işlem bekleme durumuna girer.Bazı bekleme süresi daha fazla artar ve kaynak eksikliği sorununu kontrol etme şansı yoktur. bu duruma kilitlenme denir. Aslında, kilitlenme bizim için büyük bir sorundur ve sadece çoklu görev işletim sisteminde meydana gelir. Çift görev tek görevli işletim sisteminde meydana gelemez, çünkü tüm kaynaklar sadece şu anda çalışan görev için mevcuttur ......


0

Yukarıda bazı açıklamalar güzel. Umarım bu da yararlı olabilir: https://ora-data.blogspot.in/2017/04/deadlock-in-oracle.html

Bir veritabanında, bir oturum (örneğin ora) başka bir oturum tarafından tutulan bir kaynak istediğinde (örn. Veri), ancak bu oturum (veri) aynı zamanda ilk oturum (ora) tarafından tutulan bir kaynak ister. 2'den fazla oturum da olabilir ancak fikir aynı olacaktır. Aslında, Deadlocks bazı işlemlerin çalışmaya devam etmesini önler. Örneğin: ORA-DATA'nın A kilidi tuttuğunu ve B kilidi istediğini ve SKU'nun B kilidi ve A kilidi istediğini varsayalım.

Teşekkürler,


0

Bir iş parçacığı diğer iş parçacığının bitmesini beklerken ya da tam tersi olduğunda kilitlenme oluşur.

Nasıl önlenir?
- İç İçe Kilitlerden
Kaçının - Gereksiz Kilitlerden Kaçının
- İplik birleştirme kullanın ()

Nasıl tespit edersiniz?
cmd'de bu komutu çalıştırın:

jcmd $PID Thread.print

başvuru : geeksforgeeks


0

En sık karşılaşılan neden olsa da kilitlenmeler sadece kilitlerle oluşmaz. C ++ 'da, std :: thread nesnesindeki diğeri için her thread çağrısına join () uygulayarak iki iş parçacığı ve kilitsiz kilit oluşturabilirsiniz.


0

Kilit tabanlı eşzamanlılık kontrolü

Paylaşılan kaynaklara erişimi kontrol etmek için kilitleme özelliğini kullanmak kilitlenmelere yatkındır ve yalnızca işlem zamanlayıcısı bunların oluşumunu engelleyemez.

Örneğin, ilişkisel veritabanı sistemleri işlem ACID özelliklerini garanti etmek için çeşitli kilitler kullanır .

Hangi ilişkisel veritabanı sistemini kullanırsanız kullanın, belirli bir tablo kaydını değiştirirken (örn. UPDATEVeya DELETE) kilitler her zaman edinilir . Halen çalışan bir işlemle değiştirilen bir satırı kilitlemeden Atomicity tehlikeye girer .

Kilitlenme nedir

Bu makalede açıkladığım gibi , iki eşzamanlı işlem ilerleme kaydedemediğinde bir kilitlenme meydana gelir, çünkü her biri diğerinin aşağıdaki diyagramda gösterildiği gibi bir kilit açmasını bekler.

resim açıklamasını buraya girin

Her iki işlem de kilit alma aşamasında olduğundan, ikisi de bir sonraki işlemden önce bir kilit açmaz.

Bir kilitlenme durumundan kurtarma

Kilitlere dayanan bir Eşzamanlılık Kontrol algoritması kullanıyorsanız, her zaman bir kilitlenme durumunda çalışma riski vardır. Kilitlenmeler sadece bir veritabanı sisteminde değil, herhangi bir eşzamanlılık ortamında meydana gelebilir.

Örneğin, iki veya daha fazla iş parçacığı önceden edinilmiş kilitlerde bekleyen bir iş parçacığı herhangi bir ilerleme sağlayamayacak şekilde kilitlenebilir. Bu bir Java uygulamasında gerçekleşirse, JVM yalnızca bir iş parçacığını yürütülmesini durdurmaya ve kilitlerini serbest bırakmaya zorlayamaz.

ThreadSınıf bir stopyöntemi ortaya çıkarsa bile , bu yöntem Java 1.1'den beri kullanımdan kaldırılmıştır, çünkü bir iş parçacığı durdurulduktan sonra nesnelerin tutarsız bir durumda kalmasına neden olabilir. Bunun yerine, Java birinterrupt kesintiye uğrayan bir iş parçacığı olarak bir ipucu görevi gören yöntemi ve kesintiyi görmezden gelebilir ve yürütülmesine devam edebilir.

Bu nedenle, bir Java uygulaması bir kilitlenme durumundan kurtulamaz ve kilit alma isteklerini kilitlenme asla oluşmayacak şekilde sipariş etmek uygulama geliştiricisinin sorumluluğundadır.

Ancak, belirli bir işlemin başka hangi kilitleri daha fazla elde etmek isteyeceğini öngörmek mümkün olmadığından, bir veritabanı sistemi belirli bir kilit alma siparişini uygulayamaz. Kilit sırasının korunması veri erişim katmanının sorumluluğu haline gelir ve veritabanı yalnızca bir kilitlenme durumundan kurtulmaya yardımcı olabilir.

Veritabanı motoru, geçerli çakışma grafiğini kilit bekleme döngüleri (kilitlenmelerden kaynaklanan) için tarayan ayrı bir işlem yürütür. Bir döngü algılandığında, veritabanı motoru bir işlemi alır ve iptal eder, böylece kilitlerin serbest kalmasına neden olur, böylece diğer işlem ilerleme kaydedebilir.

JVM'den farklı olarak, bir veritabanı işlemi atomik bir iş birimi olarak tasarlanmıştır. Bu nedenle, bir geri alma, veritabanını tutarlı bir durumda bırakır.

Bu konu hakkında daha fazla bilgi için bu makaleye de göz atın.


-2

Mutex özünde, paylaşılan kaynaklara korumalı erişim sağlayan bir kilittir. Linux altında, mutex iş parçacığı veri türü pthread_mutex_t şeklindedir. Kullanmadan önce başlatın.

Paylaşılan kaynaklara erişmek için muteksi kilitlemelisiniz. Muteks zaten kilitteyse, muteks kilidi açılana kadar çağrı diziyi engeller. Paylaşılan kaynaklara yapılan ziyaretin tamamlanmasının ardından, bunların kilidini açmanız gerekir.

Genel olarak, birkaç yazılı olmayan temel ilke vardır:

  • Paylaşılan kaynakları kullanmadan önce kilidi edinin.

  • Kilidi olabildiğince kısa sürede tutmak.

  • İplik bir hata döndürürse kilidi serbest bırakın.


3
Bu kilitlenmeyi değil kilitlemeyi tanımlar.
Lorne Marquis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.