Python Neden GIL İle Yazıldı?


112

Global tercüman kilidi (GIL) genellikle Python'da iş parçacığı ve benzerinin dokunma zorluğunun neden olmasının temel bir nedeni olarak gösteriliyor gibi görünüyor - "Bu neden ilk başta yapıldı?" Sorusunu gündeme getiriyor.

Programcı Olmamak, neden olabileceğine dair hiçbir fikrim yok - GIL’i koymak arkasındaki mantık neydi?


10
Wikipedia makalesi belirtiyor "GiL paralellik-bir dilin dinamizmini sahibi olmak için ödenen fiyat önünde önemli bir engel olabilir" ve söylemek gider böyle bir kilit istihdam nedenleri şunlardır:" Tek iş parçacıklı programların artan hız (tüm veri yapılarına kilitleri ayrı olarak edinme veya serbest bırakma zorunluluğu yoktur) ve genellikle iş parçacığı güvenliği olmayan C kütüphanelerinin kolay entegrasyonu. ”
Robert Harvey,

3
@RobertHarvey, Dinamizmin bununla ilgisi yok. Sorun mutasyondur.
dan_waterworth


1
Java'nın imzasız sayısal eksikliği gibi hissetmesine yardımcı olamaz, ne yaptıklarını bilmeyen insanların, kendilerini ayağından vurduklarını önlemek için tasarlanmıştı. Ne yazık ki, kimse gelmez ne yaptıklarını biliyorum gerçek bir utanç bir eksik dil, alır çünkü pek çok başka şekillerde Python kayalar
Temel

1
@Basic, şifrelemeyi şifrelemek için Java'da (uzun zamandır kullanmadım) bayt dizileriyle uğraşmanın standart bir yolu olmalı. Python (örneğin) imzalı numaralara sahip değildir, ancak daha iyi yöntemler olduğu için bit işlemlerini yapmayı denemem bile.
Nick T,

Yanıtlar:


105

Python'un birkaç uygulaması vardır, örneğin, CPython, IronPython, RPython, vb.

Bazılarında bir GIL var, bazılarında yok. Örneğin, CPython'da GIL bulunur:

Gönderen http://en.wikipedia.org/wiki/Global_Interpreter_Lock

Programlama dillerinde bir GIL ile yazılmış uygulamalar, her paralellik kendi yorumlayıcısına ve kendi CİL'sine sahip olduğundan, tam paralellik elde etmek için ayrı işlemleri kullanmak üzere tasarlanabilir.

GIL'in Faydaları

  • Tek iş parçacıklı programların artan hızı.
  • Genellikle iş parçacığı güvenliği olmayan C kütüphanelerinin kolay entegrasyonu.

Python (CPython ve diğerleri) neden GIL’i kullanıyor?

CPython'da global yorumlayıcı kilidi veya GIL, birden fazla yerel iş parçasının Python bytecode'larını aynı anda çalıştırmasını önleyen bir muteks'tir. Bu kilit özellikle CPython'un bellek yönetimi iş parçacığı güvenliği olmadığından gereklidir.

GIL tartışmalıdır çünkü çok iş parçacıklı CPython programlarının belirli durumlarda çok işlemcili sistemlerden tam olarak yararlanmasını önler. G / Ç, görüntü işleme ve NumPy numara kırma gibi potansiyel olarak engelleme veya uzun süren işlemlerin GIL dışında gerçekleştiğini unutmayın. Bu nedenle, yalnızca GIL'in içinde çok fazla zaman harcayan, CPython baytını yorumlayan, GIL'in bir darboğaz haline geldiği çok iş parçacıklı programlarda yer almaktadır.

Python çeşitli nedenlerden dolayı ince taneli kilitlemenin aksine bir GIL'ye sahiptir:

  • Tek iş parçacıklı durumda daha hızlıdır.

  • G / ç bağlı programlar için çoklu iş parçacıklı durumda daha hızlıdır.

  • C-kütüphanelerinde bilgi işlem-yoğun çalışma yapan cpu-bağlı programlar için çoklu iş parçacıklı durumda daha hızlı.

  • C uzantılarının yazılmasını kolaylaştırır: gerçekleşmesine izin verdiğiniz yer dışında Python iş parçacığı düğmesi olmayacaktır (örn. Py_BEGIN_ALLOW_THREADS ve Py_END_ALLOW_THREADS makroları arasında).

  • C kitaplıklarının sarılmasını kolaylaştırır. İplik güvenliği konusunda endişelenmenize gerek yok. Kitaplık güvenli bir şekilde güvenli değilse, GIL'yi çağırırken kilitli tutmanız yeterlidir.

GIL, C uzantılarıyla serbest bırakılabilir. Python'un standart kütüphanesi, GIL'yi her engelleme i / o çağrısı etrafında serbest bırakır. Bu nedenle GIL, bağlı sunucuların performansı için bir sonuç vermez. Böylece, Python'da ağ (network), thread veya asenkron g / Ç kullanarak ağ sunucuları oluşturabilirsiniz.

C veya Fortran'daki sayısal kütüphaneler benzer şekilde serbest bırakılan GIL ile çağrılabilir. C uzantınız bir FFT'nin tamamlanmasını beklerken, tercüman diğer Python iş parçacıklarını yürütecektir. Böylece bir GIL, bu durumda da ince ayarlı kilitlemeden daha kolay ve hızlıdır. Bu, sayısal çalışmanın büyük bölümünü oluşturur. NumPy uzantısı, mümkün olduğunda GIL'yi serbest bırakır.

Konu, çoğu sunucu programlarını yazmak için genellikle kötü bir yoldur. Yük düşükse, çatallamak daha kolaydır. Yük yüksekse, zaman uyumsuz g / ç ve olay odaklı programlama (örn. Python's Twisted framework'ü kullanarak) daha iyidir. Iş parçacığı kullanmak için tek bahane Windows'ta os.fork eksikliğidir.

GIL, saf Python'da CPU yoğun bir çalışma yapıyorsanız ve ancak eğer yapıyorsanız sorun olabilir. Burada süreçleri ve mesaj iletmeyi (örneğin mpi4py) kullanarak daha temiz tasarım elde edebilirsiniz. Ayrıca Python peynir dükkanında 'işlem' modülü de vardır, bu işlem süreçler ipliklerle aynı arayüzü verir (yani diş açmanın yerine geçer. İşlemle işlem. İşlem).

Konular, GIL'den bağımsız olarak bir GUI'nin yanıt vermesini sağlamak için kullanılabilir. GIL performansınızı bozarsa (yukarıdaki tartışmaya bakın), iş parçacığınızın bir süreci oluşturmasına ve bitmesini beklemesine izin verebilirsiniz.


52
Bana ekşi üzüm gibi geliyor. Python iş parçacığını düzgün yapamıyor, bu yüzden iş parçacığı gereksiz ya da kötü neden nedenleri telafi. "Yük düşükse, çatal kullanmak daha kolay", cidden? Ve GIL tüm bu durumlar için "daha hızlıdır", ancak referans sayma GC'yi kullanmakta ısrar ederseniz.
Michael Borgwardt

9
s/RPython/PyPy/g. @MichaelBorgwardt Profesyonellere GIL nedenleri soruyu soruyor, değil mi? Yine de, bu cevabın bazı içeriğinin (alternatiflerin tartışılması) konunun yanında olduğuna katılıyorum. Ve daha iyisi için ya da daha kötüsü için yeniden sayım yapmaktan kurtulmak neredeyse imkansız - tüm API ve kod tabanında derine gömülmüş; kodun yarısını yeniden yazmadan ve tüm harici kodları kırmadan ondan kurtulmak neredeyse imkansızdır .

10
multiprocessingKütüphaneyi unutma - 2.6'dan beri standart. İşçi havuzları, bazı basit paralellik türleri için süper kaygan bir soyutlamadır.
Sean McSomething

8
@alcalde Yalnızca ne yaptığınızı bilmiyorsanız ve / veya iş parçacıklarınızın işbirliği içinde çalışmasını / iletişim kurmasını istemiyorsanız. Aksi takdirde, özellikle bazı işletim sistemlerinde yeni bir işlem başlatmanın ek yükünü göz önünde bulundurarak, arka taraftaki kraliyet acısı. 32 çekirdekli sunucularımız var, bu yüzden bunları tamamen CPython'da kullanabilmek için 32 işleme ihtiyacım vardı. Bu "iyi bir çözüm" değil, CPython'un yetersizlikleri konusunda çalışmak bir hack.
Temel

8
İpliklerin Windows dışındaki platformlarda bulunması, çatal bıçaklamanın her durumda yeterli olmadığını kanıtlamalıdır.
zneak

42

Öncelikle: Python'un bir GIL'si yok. Python bir programlama dilidir. Bir programlama dili, soyut bir matematiksel kurallar ve kısıtlamalar kümesidir. Python Dil Belirtimi'nde GIL olması gerektiğini söyleyen hiçbir şey yoktur.

Python'un birçok farklı uygulaması var. Bazılarında GIL var, bazılarında yok.

Bir GIL'ye sahip olmanın basit bir açıklaması eşzamanlı kod yazmanın zor olmasıdır. Kodunuzun etrafına dev bir kilit koyarak, onu her zaman seri olarak çalıştırmaya zorlarsınız. Sorun çözüldü!

CPython'da, özellikle önemli bir amaç, tercümanı C ile yazılmış eklentilerle genişletmeyi kolaylaştırmaktır. Yine, eşzamanlı kod yazmak zordur, bu nedenle eşzamanlılık olmayacağını garanti ederek, eşzamanlılık yazmayı kolaylaştırır. Çevirmen. Ayrıca, bu uzantıların birçoğu aklınızdaki eşzamanlılıkla yazılmış olmayan, mevcut kitaplıkların etrafındaki ince sarmalayıcılardır.


6
Bu imzasız sayısal türleri Java'nın eksikliği gibi aynı argüman var - geliştiriciler herkes olduklarını daha aptal olduğunu düşünüyorum ...
Temel

1
@Basic - inan, inanma ya da inanma, gerçekten, gerçekten aptal olmadığında bile, işe yaraması için bazı şeyleri düşünmediğin anlamına gelen varsayımları basitleştiren bir dile sahip olmanın hala yararlı olduğu ortaya çıktı. şey. CPython, basit, çok iş parçacıklı uygulamalar (programın IO'nun bağlı olduğu, çoğu ve dolayısıyla GIL'in önemli olmadığı) dahil olduğu bazı şeyler için harikadır, çünkü GIL'i en iyi çözümü yapan tasarım kararları aynı zamanda bu uygulamaları programlamayı da kolaylaştırır. , özellikle koleksiyonlardaki atomik işlemleri desteklediği gerçeği .
Jules

@Jules Evet, bu özelliklere ihtiyaç duyana kadar çok kullanışlı. cpython'un "tercih edilen" çözümü "c ++ gibi başka bir dilde yazmanız, sonra her bir piton yararını kaybetmeniz anlamına gelir. Kodunuzun yarısını c ++ ile yazıyorsanız, neden Python'dan başlıyorsunuz? Elbette, küçük API / yapıştırıcı projeleri için hızlı ve kolaydır ve ETL için hiçbiri ikinci değildir, ancak ağır kaldırma gerektiren herhangi bir şey için uygun değildir. Donanımla konuşmak için Java kullanmakla aynı ... Atlamanız gereken çemberler neredeyse komik.
Temel

16

Bir GIL'in amacı nedir?

CAPI belgelerinin konuyla ilgili söyleyecekleri vardır:

Python yorumlayıcısı tamamen iş parçacığı için güvenli değildir. Çok iş parçacıklı Python programlarını desteklemek için, Python nesnelerine güvenle erişebilmesi için geçerli iş parçacığı tarafından tutulması gereken, genel tercüman kilidi veya GIL adı verilen genel 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ımı iki kez yerine yalnızca bir kez artırılabilir.

Başka bir deyişle, GIL devletin yolsuzluğunu önlüyor. Python programları hiçbir zaman segmentasyon hatası vermemelidir, çünkü yalnızca güvenli bellek işlemlerine izin verilir. GIL bu güvenceyi çok iş parçacıklı programlara yaymaktadır.

Alternatifler neler?

GIL’in amacı devleti yolsuzluğa karşı korumaksa, bariz bir alternatif daha ince tanelere kilitlenmektir; belki de nesne bazında. Bununla ilgili sorun, çoklu iş parçacıklı programların performansını arttırdığı gösterilmiş olmasına rağmen, bunun daha fazla genel gider ve tek iş parçacıklı programların bir sonucu olarak ortaya çıkmasıdır.


2
Kullanıcının ince taneli kilit için gili değiştiren bir tercüman seçeneği olan bir program çalıştırmasına izin vermek ve bir şekilde mevcut işlemin gil olsun olmasın, yükseltilmiş olsun olmasın salt okunur bir şekilde bilmesi harika olurdu.
Luis Masuelli

GIL rağmen çok iş parçacıklı bir programda pyodbc modülünün dikkatsiz kullanımı nedeniyle bir segmentasyon hatası üretmeyi başardım. Bu nedenle "asla bir segmentasyon hatası üretmemelisiniz" yanlış bir yanılgıdır.
Muposat
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.