Kilit (bilgisayar bilimi) - Lock (computer science)

İçinde bilgisayar Bilimi, bir kilit veya muteks (kimden Karşılıklı dışlama ) bir senkronizasyon çok sayıda ortamın olduğu bir ortamda bir kaynağa erişim sınırlarını zorlama mekanizması yürütme konuları. Bir kilit, bir Karşılıklı dışlama eşzamanlılık kontrolü politika.

Türler

Genellikle kilitler danışma kilitleri, her bir iş parçacığı, karşılık gelen verilere erişmeden önce kilidi alarak birlikte çalışır. Bazı sistemler de uygular zorunlu kilitler, kilitli bir kaynağa yetkisiz erişim girişiminde bulunmanın, istisna erişim yapmaya çalışan varlıkta.

En basit kilit türü bir ikilidir semafor. Kilitli verilere özel erişim sağlar. Diğer şemalar da verilerin okunması için paylaşılan erişim sağlar. Yaygın olarak uygulanan diğer erişim modları özeldir, hariç tutmayı amaçlamaktadır ve yükseltmeyi amaçlamaktadır.

Kilitleri sınıflandırmanın başka bir yolu, kilit stratejisi bir iş parçacığının ilerlemesini engeller. Çoğu kilitleme tasarımları blok icra of Konu kilitli kaynağa erişmesine izin verilinceye kadar kilidi talep etme. Birlikte spinlock iplik, kilit kullanılabilir hale gelene kadar basitçe bekler ("döner"). Bu, iş parçacıkları kısa bir süre için engellenirse etkilidir, çünkü işletim sistemi işlemlerinin yeniden programlanmasının ek yükünü önler. Kilidin uzun süre tutulması veya kilidi tutan ipliğin ilerlemesi kilitli ipliğin önlenmesine bağlı olması verimsizdir.

Kilitler genellikle verimli uygulama için donanım desteği gerektirir. Bu destek genellikle bir veya daha fazla şeklini alır atomik "gibi talimatlar"test et ve ayarla ", "getir ve ekle "veya"karşılaştır ve değiştir ". Bu talimatlar, tek bir işlemin kilidin serbest olup olmadığını test etmesine ve eğer serbestse kilidi tek bir atomik işlemle almasına izin verir.

Tek işlemcili mimarilerin kullanma seçeneği vardır kesintisiz diziler talimatlar - geçici olarak kesintileri devre dışı bırakmak için özel talimatlar veya talimat önekleri kullanarak - ancak bu teknik, çok işlemcili paylaşılan hafızalı makineler. Çok işlemcili bir ortamdaki kilitler için uygun destek, önemli ölçüde karmaşık donanım veya yazılım desteği gerektirebilir. senkronizasyon sorunlar.

Nedeni bir atomik operasyon Birden fazla görevin aynı mantığı yürüttüğü eşzamanlılık nedeniyle gereklidir. Örneğin, aşağıdakileri düşünün C kod:

Eğer (kilit == 0) {    // serbest bırakın, ayarlayın    kilit = myPID;}

Yukarıdaki örnek, aynı anda birden fazla görev kilidi test edebileceğinden, görevin kilide sahip olduğunu garanti etmez. Her iki görev de kilidin serbest olduğunu algılayacağından, diğer görevin de kilidi ayarladığını bilmeden her iki görev de kilidi ayarlamaya çalışacaktır. Dekker's veya Peterson algoritması atomik kilitleme işlemleri mevcut değilse olası ikamelerdir.

Kilitlerin dikkatsiz kullanımı, kilitlenme veya canlı kilit. Hem tasarım zamanında hem de tasarım sırasında kilitlenmeleri veya canlı kilitleri önlemek veya bunlardan kurtulmak için bir dizi strateji kullanılabilir. Çalışma süresi. (En yaygın strateji, kilit edinim dizilerini standartlaştırmaktır, böylece birbirine bağımlı kilit kombinasyonları her zaman özel olarak tanımlanmış bir "kademeli" sırada elde edilir.)

Bazı diller, sözdizimsel olarak kilitleri destekler. Bir örnek C # aşağıdaki gibidir:

halka açık sınıf Hesap // Bu bir hesabın izleyicisidir{    özel ondalık _denge = 0;    özel nesne _balanceLock = yeni nesne();    halka açık geçersiz Depozito(ondalık Miktar)    {        // Bu ifadeyi bir seferde yalnızca bir iş parçacığı çalıştırabilir.        kilit (_balanceLock)        {            _denge += Miktar;        }    }    halka açık geçersiz Çekil(ondalık Miktar)    {        // Bu ifadeyi bir seferde yalnızca bir iş parçacığı çalıştırabilir.        kilit (_balanceLock)        {            _denge -= Miktar;        }    }}

Kod kilitle (bu) Örneğe genel olarak erişilebiliyorsa sorunlara yol açabilir.[1]

Benzer Java C #, MethodImplOptions.Synchronized özniteliğini kullanarak tüm yöntemleri de eşitleyebilir.[2][3]

[MethodImpl (MethodImplOptions.Synchronized)]halka açık geçersiz SomeMethod(){    // şeyler yapmak}

Ayrıntı düzeyi

Ayrıntı düzeyini kilitlemek için kullanılmadan önce, kilitlerle ilgili üç kavramın anlaşılması gerekir:

  • yükü kilitlemek: kilitler için ayrılan bellek alanı, CPU'nun kilitleri başlatma ve yok etme süresi ve kilitleri alma veya serbest bırakma zamanı gibi kilitleri kullanmak için ekstra kaynaklar. Bir program ne kadar çok kilit kullanırsa, kullanımla ilgili daha fazla ek yük;
  • kilit çekişme: bu, bir işlem veya iş parçacığı başka bir işlem veya iş parçacığı tarafından tutulan bir kilidi almaya çalıştığında ortaya çıkar. Mevcut kilitler ne kadar ince taneli olursa, bir işlemin / iş parçacığının diğeri tarafından tutulan bir kilit talep etme olasılığı o kadar düşüktür. (Örneğin, tablonun tamamı yerine bir satırı kilitlemek veya tüm satır yerine bir hücreyi kilitlemek.);
  • kilitlenme: en az iki görevden her birinin, diğer görevin tuttuğu bir kilit beklediği durum. Bir şey yapılmadıkça, iki görev sonsuza kadar bekleyecektir.

Senkronizasyondaki kilit sayısını seçerken kilit ek yükünü azaltmak ve kilit çekişmesini azaltmak arasında bir denge vardır.

Bir kilidin önemli bir özelliği, taneciklik. Ayrıntı düzeyi, kilidin koruduğu veri miktarının bir ölçüsüdür. Genel olarak, kaba bir taneciklik seçmek (her biri büyük bir veri bölümünü koruyan az sayıda kilit), daha az yükü kilitlemek tek bir işlem korunan verilere erişirken, ancak birden çok işlem aynı anda çalışırken daha kötü performans. Bunun nedeni artmış çekişmeyi kilitlemek. Kilit ne kadar kaba olursa, kilidin ilgisiz bir sürecin ilerlemesini durdurma olasılığı o kadar yüksek olur. Tersine, ince bir ayrıntı düzeyi (her biri oldukça az miktarda veriyi koruyan daha fazla sayıda kilit) kullanmak, kilitlerin ek yükünü artırır ancak kilit çekişmesini azaltır. Her işlemin ortak bir kilit kümesinden birden fazla kilit tutması gereken granüler kilitleme, ince kilit bağımlılıkları oluşturabilir. Bu incelik, bir programcının farkında olmadan bir kilitlenme.[kaynak belirtilmeli ]

İçinde veritabanı Yönetim sistemi örneğin, bir kilit, granülerliği azaltma sırasına göre bir alanın bir bölümünü, bir alanı, bir kaydı, bir veri sayfasını veya bir tablonun tamamını koruyabilir. Tablo kilitleri kullanmak gibi kaba taneciklik, tek bir kullanıcı için en iyi performansı verme eğilimindeyken, kayıt kilitleri gibi ince taneciklik, birden çok kullanıcı için en iyi performansı verme eğilimindedir.

Veritabanı kilitleri

Veritabanı kilitleri işlem eşzamanlılığını sağlamak için bir araç olarak kullanılabilir. yani eşzamanlı işlem gerçekleştirirken (araya giren işlemler), 2 aşamalı kilitler işlemin eşzamanlı olarak yürütülmesinin, işlemin bazı seri siparişlerine eşdeğer olmasını sağlar. Ancak, kilitlenmeler, veritabanlarında kilitlenmenin talihsiz bir yan etkisi haline gelir. Kilitlenmeler, işlemler arasında kilitleme sırasının önceden belirlenmesiyle önlenir veya bekleyen grafikler. Kilitlenmelerden kaçınırken veritabanı eşzamanlılığı için kilitlemenin bir alternatifi, tamamen sıralı küresel zaman damgalarının kullanılmasını içerir.

Birden çok eylemi yönetmek için kullanılan mekanizmalar vardır. eşzamanlı kullanıcılar bir veritabanında — amaç, kayıp güncellemeleri ve kirli okumaları önlemektir. İki tür kilitleme vardır karamsar kilitleme ve iyimser kilitleme:

  • Karamsar kilitleme: bir kaydı güncelleme niyetiyle okuyan bir kullanıcı, diğer kullanıcıların onu değiştirmesini önlemek için kayda özel bir kilit yerleştirir. Bu, kullanıcı kilidi açana kadar hiç kimsenin bu kaydı değiştiremeyeceği anlamına gelir. Dezavantajı, kullanıcıların çok uzun bir süre dışarıda kalabilmesidir, bu nedenle genel sistem yanıtını yavaşlatır ve hayal kırıklığına neden olur.
Kötümser kilitlemenin nerede kullanılacağı: Bu, esas olarak veri çekişmesinin (kullanıcıların herhangi bir zamanda veritabanı sistemine taleplerinin derecesi) ağır olduğu ortamlarda kullanılır; Verileri kilitlerle korumanın maliyeti, eşzamanlılık çakışmaları meydana gelirse işlemlerin geri alınma maliyetinden daha az olduğunda. Karamsar eşzamanlılık, kayıtların programlı olarak işlenmesinde olduğu gibi kilit sürelerinin kısa olacağı durumlarda en iyi şekilde uygulanır. Kötümser eşzamanlılık, veri tabanına kalıcı bir bağlantı gerektirir ve kullanıcılar verilerle etkileşimde bulunurken ölçeklenebilir bir seçenek değildir, çünkü kayıtlar nispeten uzun süreler boyunca kilitlenebilir. Web uygulaması geliştirmede kullanılması uygun değildir.
  • İyimser kilitleme: Bu, birden çok eşzamanlı kullanıcının veritabanına erişmesine izin verirken, sistem her kullanıcı tarafından yapılan ilk okumanın bir kopyasını tutar. Bir kullanıcı bir kaydı güncellemek istediğinde, uygulama, başka bir kullanıcının son okunduğundan beri kaydı değiştirip değiştirmediğini belirler. Uygulama, kayıtta yapılan herhangi bir değişikliği doğrulamak için bellekte tutulan ilk okumayı veritabanı kaydı ile karşılaştırarak bunu yapar. İlk okuma ile veritabanı kaydı arasındaki herhangi bir tutarsızlık eşzamanlılık kurallarını ihlal eder ve dolayısıyla sistemin herhangi bir güncelleme talebini göz ardı etmesine neden olur. Bir hata mesajı oluşturulur ve kullanıcıdan güncelleme işlemini yeniden başlatması istenir. Gereken kilitleme miktarını azaltarak veritabanı performansını artırır ve böylece veritabanı sunucusundaki yükü azaltır. Hiçbir kullanıcı kilitlenmediğinden sınırlı güncelleme gerektiren tablolarla verimli bir şekilde çalışır. Ancak bazı güncellemeler başarısız olabilir. Bunun dezavantajı, birden çok eşzamanlı kullanıcıdan gelen yüksek hacimli güncelleme taleplerinden kaynaklanan sürekli güncelleme hatalarıdır - bu, kullanıcılar için can sıkıcı olabilir.
İyimser kilitlemenin nerede kullanılacağı: Bu, veri çekişmesinin düşük olduğu veya verilere salt okunur erişimin gerekli olduğu ortamlar için uygundur. İyimser eşzamanlılık, .NET'te mobil ve bağlantısız uygulamaların ihtiyaçlarını karşılamak için yaygın olarak kullanılır,[4] veri satırlarını uzun süreler için kilitlemenin mümkün olmadığı durumlarda. Ayrıca, kayıt kilitlerini korumak, veri tabanı sunucusuna kalıcı bir bağlantı gerektirir ve bağlantısı kesilen uygulamalarda bu mümkün değildir.

Dezavantajları

Kilit tabanlı kaynak koruması ve iş parçacığı / işlem senkronizasyonunun birçok dezavantajı vardır:

  • Çatışma: Bazı iş parçacıkları / süreçler bir kilit (veya bir dizi kilit) serbest kalana kadar beklemek zorundadır. Kilidi tutan ipliklerden biri ölürse, durursa, bloke olursa veya sonsuz bir döngüye girerse, kilidi bekleyen diğer iplikler sonsuza kadar bekleyebilir.
  • Genel gider: Kilitlerin kullanımı, çarpışma olasılığı çok nadir olsa bile, bir kaynağa her erişim için ek yük getirir. (Ancak, bu tür çarpışmalar için herhangi bir şans, yarış kondisyonu.)
  • Hata ayıklama: kilitlerle ilişkili hatalar zamana bağlıdır ve çok ince ve çoğaltılması son derece zor olabilir. kilitlenmeler.
  • Kararsızlık: Kilit ek yükü ile kilit çekişmesi arasındaki optimum denge, sorun alanına (uygulama) özgü olabilir ve tasarıma, uygulamaya ve hatta düşük düzeyli sistem mimari değişikliklerine duyarlı olabilir. Bu bakiyeler, bir uygulamanın yaşam döngüsü boyunca değişebilir ve güncelleme için çok büyük değişiklikler gerektirebilir (yeniden dengeleme).
  • Birleştirilebilirlik: kilitler, nispeten ayrıntılı (genel gider) yazılım desteği ve sıkı kurallara uygulama programlamasıyla mükemmel uyum ile yalnızca birleştirilebilir (örneğin, X öğesini tablo A'dan atomik olarak silmek ve X'i tablo B'ye eklemek için birden fazla eşzamanlı kilidi yönetmek).
  • Öncelikli ters çevirme: ortak bir kilidi tutan düşük öncelikli bir iş parçacığı / işlem, yüksek öncelikli iş parçacıkları / işlemlerin ilerlemesini önleyebilir. Öncelikli miras önceliği tersine çevirme süresini azaltmak için kullanılabilir. öncelikli tavan protokolü en kötü durum önceliğini ters çevirme süresini en aza indirmek ve aynı zamanda önlemek için tek işlemcili sistemlerde kullanılabilir. kilitlenme.
  • Konvoy: diğer tüm iş parçacığı, bir zaman dilimi kesintisi veya sayfa hatası nedeniyle bir kilidi tutan bir iş parçacığının planının kaldırılması durumunda beklemek zorundadır.

Biraz eşzamanlılık kontrolü stratejiler bu sorunların bir kısmını veya tamamını önler. Örneğin, bir huni veya belirteçleri serileştirme en büyük sorunu önleyebilir: kilitlenmeler. Kilitlemeye alternatifler şunları içerir: engellemeyen senkronizasyon yöntemler, gibi kilitsiz programlama teknikleri ve işlem belleği. Bununla birlikte, bu tür alternatif yöntemler çoğu zaman gerçek kilit mekanizmalarının işletim yazılımının daha temel bir seviyesinde uygulanmasını gerektirir. Bu nedenle, yalnızca uygulama Kilit uygulama ayrıntılarından, yukarıda listelenen sorunların hala uygulamanın altında ele alınması gerekir.

Çoğu durumda, uygun kilitleme, CPU'nun atomik komut akışı senkronizasyonu yöntemi sağlamasına bağlıdır (örneğin, bir öğenin bir boru hattına eklenmesi veya silinmesi, boruya diğer öğeleri eklemek veya silmek için gereken tüm eşzamanlı işlemlerin sırasında askıya alınmasını gerektirir. belirli bir öğeyi eklemek veya silmek için gereken bellek içeriğinin değiştirilmesi). Bu nedenle, bir uygulama, bir işletim sistemine yüklediği yükleri anladığında ve imkansız taleplerin raporlanmasını nezaketle tanıyabildiğinde genellikle daha sağlam olabilir.[kaynak belirtilmeli ]

Düzenlenebilirlik eksikliği

Kilit tabanlı programlamanın en büyük sorunlarından biri, "kilitlerin oluşturmak ": Küçük, doğru kilit tabanlı modülleri, modülleri değiştirmeden veya en azından iç kısımlarını bilmeden eşit derecede doğru daha büyük programlarda birleştirmek zordur. Simon Peyton Jones (bir savunucusu yazılım işlem belleği ) aşağıdaki bankacılık uygulaması örneğini verir:[5]bir sınıf tasarla Hesap aynı anda birden fazla müşterinin bir hesaba para yatırmasına veya çekmesine izin veren; ve bir hesaptan diğerine para transfer etmek için bir algoritma verin. Sorunun ilk kısmının kilit tabanlı çözümü şudur:

sınıf Hesap: üye denge: Tamsayı üye mutex: Kilitle yöntem deposit (n: Tamsayı) mutex.lock () bakiye ← bakiye + n mutex.unlock () yöntem para çekme (n: Tamsayı) depozito (−n)

Sorunun ikinci kısmı çok daha karmaşık. Bir Aktar doğru olan rutin sıralı programlar için olabilir

işlevi havale (kimden: Hesap, tutar: tamsayı) - para çekme (tutar) - mevduat (tutar)

Eşzamanlı bir programda, bu algoritma yanlıştır çünkü bir iş parçacığı yarı yolda olduğunda Aktarbir başkası bir durumu gözlemleyebilir Miktar ilk hesaptan çekildi, ancak henüz diğer hesaba yatırılmadı: sistemden para kayboldu. Bu sorun, yalnızca iki hesaptan herhangi birini değiştirmeden önce her iki hesaba da kilitler alınarak tamamen çözülebilir, ancak kilitlenmeyi önlemek için kilitlerin bazı rasgele, genel sıralamaya göre alınması gerekir:

işlevi transfer (kimden: Hesap, kime: Hesap, tutar: tamsayı) Eğer // kilitler üzerinde keyfi sıralama        from.lock () to.lock () Başka        to.lock () from.lock () from.withdraw (tutar) to.deposit (tutar) from.unlock () to.unlock ()

Daha fazla kilit söz konusu olduğunda bu çözüm daha karmaşık hale gelir ve Aktar işlevin tüm kilitler hakkında bilgi sahibi olması gerekir, bu nedenle gizli.

Dil desteği

Programlama dilleri, senkronizasyon desteğine göre değişir:

  • Ada görünür korumalı alt programları veya girdileri olan korumalı nesneler sağlar[6] yanı sıra randevu.[7]
  • ISO / IEC C standart bir standart sağlar Karşılıklı dışlama (kilitler) API dan beri C11. Mevcut ISO / IEC C ++ standart destekler diş açma tesisleri dan beri C ++ 11. OpenMP standardı bazı derleyiciler tarafından desteklenir ve kritik bölümlerin pragmalar kullanılarak belirlenmesine izin verir. POSIX pthread API, kilit desteği sağlar.[8] Görsel C ++ sağlar senkronize etmek eşitlenecek yöntemlerin özniteliği, ancak bu, içindeki COM nesnelerine özgüdür. pencereler mimari ve Görsel C ++ derleyici.[9] C ve C ++, herhangi bir yerel işletim sistemi kilitleme özelliğine kolayca erişebilir.
  • C # sağlar kilit bir kaynağa özel erişimini sağlamak için bir iş parçacığındaki anahtar kelime.
  • VB.NET sağlar SyncLock C # gibi anahtar kelime kilit anahtar kelime.
  • Java anahtar kelimeyi sağlar senkronize kod bloklarını kilitlemek için, yöntemler veya nesneler[10] ve eşzamanlılık açısından güvenli veri yapıları içeren kitaplıklar.
  • Amaç-C anahtar kelimeyi sağlar @synchronized[11] kod bloklarına kilitler koymak ve ayrıca NSLock sınıflarını sağlar,[12] NSRecursiveLock,[13] ve NSConditionLock[14] NSLocking protokolü ile birlikte[15] de kilitlemek için.
  • PHP dosya tabanlı kilitleme sağlar [16] yanı sıra Mutex sınıf pthreads uzantı. [17]
  • Python düşük seviye sağlar muteks mekanizma Kilit sınıftan iş parçacığı modül.[18]
  • ISO / IEC Fortran standardı (ISO / IEC 1539-1: 2010) şunları sağlar: Kilit tipi iç modülde türetilmiş tür iso_fortran_env ve kilit/Kilidini aç o zamandan beri ifadeler Fortran 2008.[19]
  • Yakut düşük seviye sağlar muteks nesne ve anahtar kelime yok.[20]
  • Pas, paslanma sağlar Mutex [21] struct.[22]
  • x86 montajı sağlar KİLİT atomikliğini garanti altına almak için belirli işlemlerde önek.

Ayrıca bakınız

Referanslar

  1. ^ "lock İfadesi (C # Başvurusu)".
  2. ^ "ThreadPoolPriority ve MethodImplAttribute". http://msdn.microsoft.com/en-us/magazine/cc163896.aspx: MSDN. s. ??. Alındı 2011-11-22.CS1 Maint: konum (bağlantı)
  3. ^ "Java Geliştiricisinin Perspektifinden C #". http://www.25hoursaday.com/CsharpVsJava.html#attributes. Arşivlenen orijinal 2013-01-02 tarihinde. Alındı 2011-11-22.CS1 Maint: konum (bağlantı)
  4. ^ "Veri Katmanı Bileşenlerini Tasarlama ve Verileri Katmanlardan Aktarma". Microsoft. Ağustos 2002. Arşivlenen orijinal 2008-05-08 tarihinde. Alındı 2008-05-30.
  5. ^ Peyton Jones, Simon (2007). "Güzel eşzamanlılık" (PDF). Wilson'da, Greg; Oram Andy (editörler). Güzel Kod: Önde Gelen Programcılar Nasıl Düşündüklerini Açıklıyor. O'Reilly.
  6. ^ ISO / IEC 8652: 2007. "Korunan Birimler ve Korunan Nesneler". Ada 2005 Referans Kılavuzu. Alındı 2010-02-27. Korunan bir nesne, korunan alt programlar veya korumalı girişler olabilen görünür korumalı işlemlerine yapılan çağrılar aracılığıyla paylaşılan verilere koordineli erişim sağlar.
  7. ^ ISO / IEC 8652: 2007. "Görevlendirme ve Senkronizasyon Örneği". Ada 2005 Referans Kılavuzu. Alındı 2010-02-27.
  8. ^ Marshall, Dave (Mart 1999). "Karşılıklı Hariç Tutma Kilitleri". Alındı 2008-05-30.
  9. ^ "Senkronize et". msdn.microsoft.com. Alındı 2008-05-30.
  10. ^ "Senkronizasyon". Sun Microsystems. Alındı 2008-05-30.
  11. ^ "Apple Diş Açma Referansı". Apple, inc. Alındı 2009-10-17.
  12. ^ "NSLock Referansı". Apple, inc. Alındı 2009-10-17.
  13. ^ "NSRecursiveLock Referansı". Apple, inc. Alındı 2009-10-17.
  14. ^ "NSConditionLock Referansı". Apple, inc. Alındı 2009-10-17.
  15. ^ "NSLocking Protokol Referansı". Apple, inc. Alındı 2009-10-17.
  16. ^ "sürü".
  17. ^ "Mutex sınıfı".
  18. ^ Lundh, Fredrik (Temmuz 2007). "Python'da İş Parçacığı Senkronizasyon Mekanizmaları". Alındı 2008-05-30.
  19. ^ John Reid (2010). "Yeni Fortran Standardında Coarrays" (PDF). Alındı 2020-02-17.
  20. ^ "Ruby Programlama: İş Parçacıkları ve İşlemler". 2001. Alındı 2008-05-30.
  21. ^ "std :: sync :: Mutex - Pas". doc.rust-lang.org. Alındı 3 Kasım 2020.
  22. ^ "Paylaşılan Durum Eşzamanlılığı - Rust Programlama Dili". doc.rust-lang.org. Alındı 3 Kasım 2020.

Dış bağlantılar