Son 15 yılda Herlihy ve Wing'i birçok kez tekrar okudum. Okuması çok zor. Ve bu talihsiz bir durum, çünkü kenarlarda bazı incelikler varken, temel fikir aslında oldukça makul.
Kısacası: doğrusallaştırılabilir serileştirilebilirlik gibidir, ancak serileştirmenin işlemler arasındaki ek sipariş kısıtlamalarına uyması şartıyla. Amaç, tüm sistemi bir kerede düşünmek yerine, tek bir atomik veri yapısı hakkında titizlikle akıl yürütmenize izin vermektir.
Doğrusallaştırılabilirlik elde etmek de kolaydır: bir muteksi doğrusallaştırmak istediğiniz nesne ile ilişkilendirin. Bu nesne üzerindeki her işlem muteksi kilitleyerek başlar ve muteksin kilidini açarak sona erer.
İşte kullanacağım tanımlar:
Bir sistem olup serializabile veri kümesi üzerinde bir set işlem verilirse gibi, işlemlerinde herhangi bir sonuç aynı işlemlerin bazı sırayla gerçekleştirildi ve her bir işlem içinde işlemleri için kendi işlem içinde yer alır işlem koduyla belirtilir.
Serileştirilebilirlik, farklı işlemler arasındaki işlemlerin harmanlanması görünümüne izin vermez ve seçilen işlem sırasının nedenselliğe uymasını gerektirir (A işlemi x değerini yazarsa ve B işlemi A'nın yazdığı x değerini okursa, A işlemi B işleminden önce gelmelidir Ancak, işlemlerin sıralanmasındaki diğer kısıtlamalar hakkında hiçbir şey söylemez (özellikle süreçler ve süreçlerin olayları algılama sırası hakkında hiçbir şey söylemez .)
İşlemlerin yürütüldüğü işlemlerin sırası hakkında kısıtlamalar ekleyen (ancak yalnızca bireysel okuma / yazma işlemlerinden bahsetmeyen) ilgili başka bir fikir vardır:
Herhangi bir yürütmenin sonucu, tüm işlemlerin işlemlerinin ardışık bir sırada yürütülmesi ile aynıysa ve her bir işlemin işlemleri bu sırayla programı tarafından belirtilen sırayla görünürse, bir sistem sıralı olarak tutarlıdır . ( Lamport, "Çok İşlemcili Programları Doğru Olarak Yürüten Çok İşlemcili Bir Bilgisayar Nasıl Yapılır", IEEE T Comp 28: 9 (690-691), 1979 ).
Sıralı tutarlılığın tanımında örtük olan, yalnızca her bellek konumu (nesne) için uyarılan sıralı işlem sırasının, her okuma işlemi tarafından konuma döndürülen x
değerin, x
sıraya göre hemen önceki yazma işlemi .
Doğrusallaştırılabilirlik iyi niyete sahiptir (a) işlem kavramını (serileştirmeden), süreçlerin düzenledikleri işlemlerin sırayla (sıralı tutarlılıktan) tamamlanmasını bekledikleri ve (b) her biri hakkında konuşmak için doğruluk kriterlerini daraltmak düşüncesi ile birleştirmek sizi bir bütün olarak sistem hakkında akıl yürütmeye zorlamak yerine, tecrit halinde. (Doğrusallaştırılamayan başka nesnelerin olduğu bir sistemde bile nesnemin uygulamasının doğru olduğunu söylemek isterim.) Herlihy ve Wing'in bir monitörü titizlikle tanımlamaya çalıştığına inanıyorum .
Bölüm (a) "kolaydır": Sıralı bir tutarlılık benzeri gereklilik, her işlem tarafından yayınlanan nesne üzerindeki işlemlerin, program tarafından belirtilen sırayla ortaya çıkan sırada görünmesidir. Serileştirme benzeri bir gereklilik, nesne üzerindeki işlemlerin birbirini dışlamasıdır (serileştirilebilir).
Karmaşıklık amaç (b) 'den kaynaklanır (her bir nesne hakkında diğerlerinden bağımsız olarak konuşabilmek).
Birden çok nesneye sahip bir sistemde, B nesnesindeki işlemlerin, işlemlerin A nesnesine çağrıldığına inandığımız sırayla kısıtlamalar koyması mümkündür. Tüm sistem geçmişine bakarsak, belirli sıralı siparişlerle kısıtlanırız ve başkalarını reddetmesi gerekecek. Ancak, tek başına kullanabileceğimiz bir doğruluk kriteri istedik (A nesnesine küresel sistem geçmişine hitap etmeden ne olduğu hakkında akıl yürütme).
Örneğin: bir kuyruk olan A nesnesinin doğruluğu hakkında tartışmaya çalıştığımı varsayalım, B nesnesinin bir bellek konumu olduğunu varsayalım ve aşağıdaki yürütme geçmişlerine sahip olduğumu varsayalım: İş parçacığı 1: A.enqueue (x), A. dequeue () (y değerini döndürür). Konu 2: A. enqueue (y), A.dequeue () (x değerini döndürür). Sıranın bu uygulamasının doğru olmasına izin verecek olaylar arasında bir araya ekleme var mı? Evet:
Thread 1 Thread 2
A.enqueue(x) ...
... A.enqueue(y)
... A.dequeue() (returns x)
A.dequeue(y) (returns y) ...
Ama şimdi tarih ( B nesnesi dahil ) ise: B 0 değeri ile başlar. 1: A.enqueue (x), A.dequeue () (y döndürür), B.write (1). İş parçacığı 2: B.read () (1 döndürür) A.enqueue (y), A.dequeue () (x döndürür).
Thread 1 Thread 2
A.enqueue(x) ...
A.dequeue() (returns y) ... (uh oh!)
B.write(1) ...
... B.read() (returns 1)
... A.enqueue(y)
... A.dequeue() (returns x)
Şimdi "doğruluk" tanımımızın bu tarihin ya A uygulamamızın ya da B uygulamamızın buggy olduğunu belirtmesini istiyoruz, çünkü "mantıklı" bir serileştirme yok (2. B'den henüz yazılmamış bir değer veya İş Parçacığı 1'in A'dan henüz henüz hesaplanmamış bir değeri alması gerekir.) Dolayısıyla, A'daki işlemlerin orijinal serileştirmesi makul bir değer gibi görünüyordu, eğer uygulamamız ikincisi gibi bir tarihe izin verirse, o zaman açıkça yanlıştır.
Dolayısıyla, doğrusallaştırmanın eklediği kısıtlamalar oldukça mantıklıdır (ve FIFO kuyrukları gibi basit veri yapıları için bile gereklidir.) Bunlar şöyledir: "uygulamanız, dequeue'ya (), geleceği." Doğrusallaştırılabilirliği elde etmek oldukça kolaydır (ve doğaldır): sadece bir muteksi nesnenizle ilişkilendirin ve her işlem kilitleme ile başlar ve kilidini açarak sona erer. Atomisitenizi basit muteksler yerine bloke olmayan veya kilitsiz veya bekleme gerektirmeyen tekniklerle uygulamaya çalıştığınızda lineerleştirilebilirlik hakkında akıl almaz hale gelir.
Literatüre bazı işaretçilerle ilgileniyorsanız, aşağıdakileri buldum ("gerçek zamanlı" hakkındaki tartışma, lineerizabilty'i olması gerekenden daha zor hale getiren kırmızı ringalardan biri olduğunu düşünüyorum.) Https: // stackoverflow.com/questions/4179587/difference-between-linearizability-and-serializability