Python'un Global Tercüman Kilidinin işlevi tam olarak nedir? Bayt koduna göre derlenen diğer diller benzer bir mekanizma kullanıyor mu?
Python'un Global Tercüman Kilidinin işlevi tam olarak nedir? Bayt koduna göre derlenen diğer diller benzer bir mekanizma kullanıyor mu?
Yanıtlar:
Genel olarak, herhangi bir iş parçacığı güvenliği sorunu için dahili veri yapılarınızı kilitlerle korumanız gerekecektir. Bu, çeşitli ayrıntı düzeyleriyle yapılabilir.
Her ayrı yapının kendi kilidine sahip olduğu ince taneli kilitlemeyi kullanabilirsiniz.
Tek bir kilidin her şeyi koruduğu (GIL yaklaşımı) kaba taneli kilitlemeyi kullanabilirsiniz.
Her yöntemin çeşitli artıları ve eksileri vardır. İnce taneli kilitleme, daha fazla paralellik sağlar - iki iş parçacığı, herhangi bir kaynağı paylaşmadıklarında paralel olarak yürütülebilir. Ancak çok daha büyük bir idari ek yük var. Her kod satırı için birkaç kilit almanız ve bırakmanız gerekebilir.
Kaba taneli yaklaşım bunun tersidir. İki iş parçacığı aynı anda çalışamaz, ancak tek bir iş parçacığı daha hızlı çalışır çünkü çok fazla muhasebe yapmaz. Sonuçta, tek iş parçacıklı hız ve paralellik arasında bir değiş tokuşa varılır.
Python'da GIL'i kaldırmak için birkaç girişimde bulunuldu, ancak tek iş parçacıklı makineler için fazladan yük genellikle çok büyüktü. Kilit çekişmesi nedeniyle bazı durumlar çok işlemcili makinelerde bile daha yavaş olabilir.
Bayt koduna göre derlenen diğer diller benzer bir mekanizma kullanıyor mu?
Değişiklik gösterir ve muhtemelen bir uygulama özelliği kadar bir dil özelliği olarak düşünülmemelidir. Örneğin, Jython ve IronPython gibi bir GIL yaklaşımı yerine temeldeki sanal makinelerinin iş parçacığı yaklaşımını kullanan Python uygulamaları vardır. Ek olarak, Ruby'nin bir sonraki sürümü bir GIL sunmaya doğru ilerliyor gibi görünüyor .
Aşağıdakiler, resmi Python / C API Referans Kılavuzundan alınmıştır :
Python yorumlayıcısı tam olarak iş parçacığı güvenli değildir. Çok iş parçacıklı Python programlarını desteklemek için, Python nesnelerine güvenli bir şekilde erişmeden önce mevcut iş parçacığı tarafından tutulması gereken global bir kilit vardır. Kilit olmadan, en basit işlemler bile çok iş parçacıklı bir programda sorunlara neden olabilir: örneğin, iki iş parçacığı aynı nesnenin referans sayısını aynı anda artırdığında, referans sayısı iki yerine yalnızca bir kez artırılabilir.
Bu nedenle, kural, yalnızca global yorumlayıcı kilidini alan iş parçacığının Python nesneleri üzerinde çalışabileceği veya Python / C API işlevlerini çağırabileceği şeklinde mevcuttur. Çok iş parçacıklı Python programlarını desteklemek için, yorumlayıcı kilidi düzenli olarak serbest bırakır ve yeniden alır - varsayılan olarak, her 100 bayt kodu talimatını (bu sys.setcheckinterval () ile değiştirilebilir). Kilit ayrıca, bir dosyayı okumak veya yazmak gibi potansiyel olarak engelleyici G / Ç işlemleri etrafında serbest bırakılır ve yeniden elde edilir, böylece G / Ç'yi isteyen iş parçacığı G / Ç işleminin tamamlanmasını beklerken diğer iş parçacıkları çalışabilir.
Sanırım sorunu oldukça iyi özetliyor.
Global yorumlayıcı kilidi, referans sayaçlarının ıslanmasını önleyen büyük bir muteks tipi kilittir. Saf python kodu yazıyorsanız, bunların hepsi perde arkasında gerçekleşir, ancak Python'u C'ye yerleştirirseniz, kilidi açıkça almanız / bırakmanız gerekebilir.
Bu mekanizma, Python'un bayt koduna derlenmesiyle ilgili değildir. Java için gerekli değildir. Aslında, Jython için bile gerekli değildir (python, jvm'ye derlenmiştir).
ayrıca bu soruya bakın
Python, perl 5 gibi, sıfırdan iş parçacığı için güvenli olacak şekilde tasarlanmamıştır. İplikler olaydan sonra aşılandı, bu nedenle küresel yorumlayıcı kilidi, yorumlayıcının bağırsaklarında belirli bir zamanda yalnızca bir iş parçacığının kod yürüttüğü yerde karşılıklı dışlamayı sağlamak için kullanılır.
Bireysel Python iş parçacıkları, kilidin sık sık çevrilmesiyle tercümanın kendisi tarafından işbirliği içinde çoklu görev gerçekleştirir.
Diğer Python iş parçacıkları bu protokole 'katılmak' için aktifken ve arkanızda güvensiz hiçbir şeyin olmadığından emin olmak için C'den Python ile konuşurken kilidi kendiniz almanız gerekir.
Daha sonra çok iş parçacıklı sistemlere dönüşen tek iş parçacıklı bir mirasa sahip diğer sistemler, genellikle bu türden bir mekanizmaya sahiptir. Örneğin, Linux çekirdeği SMP'nin ilk günlerinden itibaren "Büyük Çekirdek Kilidi" ne sahiptir. Zaman içinde kademeli olarak, çoklu iş parçacığı performansı bir sorun haline geldikçe, bu tür kilitleri daha küçük parçalara ayırmaya veya mümkün olan yerlerde verimliliği en üst düzeye çıkarmak için kilitsiz algoritmalar ve veri yapılarıyla değiştirmeye çalışma eğilimi vardır.
reiserfs
- bunu bildiğim tek gerçek neden) kullanıldığından bahsettiği için .
İkinci sorunuzla ilgili olarak, tüm komut dosyası dilleri bunu kullanmaz, ancak yalnızca onları daha az güçlü hale getirir. Örneğin, Ruby'deki diziler yeşildir ve yerel değildir.
Python'da, iş parçacıkları yereldir ve GIL yalnızca bunların farklı çekirdekler üzerinde çalışmasını engeller.
Perl'de iplikler daha da kötü. Tüm yorumlayıcıyı kopyalarlar ve Python'daki kadar kullanılabilir olmaktan uzaktırlar.
Belki BDFL tarafından hazırlanan bu makale yardımcı olacaktır.