Soru Neden bir Python G / Ç bağlı görevi GIL tarafından engellenmez?


piton threading belgelere göre "... iş parçacığı hala uygun bir modeldir Birden çok G / Ç bağlı görevi aynı anda çalıştırmak istiyorsanız ", Görünüşe göre, G / Ç bağlı süreçler önleyen GIL'yi önleyebilir CPU'ya bağlı görevlerde eşzamanlı yürütme iş parçacıkları.

Ama anlamadığım şey bir G / Ç görevinin hala CPU kullanıyor olmasıdır. Yani Aynı sorunları nasıl karşılayamaz? G / Ç olduğundan bağlı görev bellek yönetimi gerektirmez?


24
2018-03-26 03:52


Menşei


"G / Ç görevi hala CPU kullanıyor" ... genel olarak durum böyle değil. PIO yerine, birçok / en modern çevre birimi, verileri taşımak için CPU döngüleri gerektirmeyen doğrudan bellek erişimine sahiptir. - Brian Cain


Cevaplar:


CPython'da GIL1 olduğu bir tek yürütülmekte olan Python koduyla ilgili. Çok fazla CPU kullanan bir iş parçacığı güvenli C uzantısı, Python çalışma zamanı ile etkileşime girmesi gerekmediği sürece GIL'yi serbest bırakabilir.

C kodunun Python'a “konuşması” gerektiğinde (okuyun: Python çalışma zamanına geri dönün), o zaman GIL'in tekrar elde edilmesi gerekir - yani GIL, “yorumlayıcı” için koruma / atomik davranış oluşturmaktır. ve terimini gevşek olarak kullanıyorum) ve değil Yerel / Python olmayan kodun aynı anda çalışmasını engellemek için.

GIL'in G / Ç çevresinde serbest bırakılması (CPU kullanarak veya değil, engelleme veya engelleme) aynı şeydir - veri taşınana kadar içine Python GIL'i elde etmek için bir sebep yok.


1 GIL tartışmalı bir konudur çünkü çok iş parçacıklı CPython programlarının belirli durumlarda çok işlemcili sistemlerden tam olarak yararlanmasını engeller. G / Ç, görüntü işleme ve NumPy sayısı gibi olası engelleme veya uzun süren işlemlerin GIL dışında gerçekleştiğini unutmayın. bu nedenle Sadece GIL içinde çok fazla zaman harcayan ve CPython bayt kodunu yorumlayan çok iş parçacıklı programlardaGIL bir darboğaz haline gelir.


17
2018-03-26 04:12





I / O bloğunun çözülmesini beklerken, Python'un tüm engelleme I / O ilkellerinin tümü GIL'yi serbest bırakır; Tabii ki daha fazla Python kodunu yürütmeden önce GIL'i tekrar elde etmek zorunda kalacaklar, ancak bazı I / O syscall'larını bekledikleri uzun-dönem-makine-döngü aralıkları için GIL'e ihtiyacı yok, o yüzden buna dayanmıyorlar!


27
2018-03-26 03:55



@Shashank, nah - Ben "C ++ I / O bağlı kod C ++ etrafında daireler çalışan C ++ I / O ilişkili kod" - "," doğal olarak kodlanmış "Python - iki, üç kat daha hızlı. GIL'i düşürmek her zaman süper hızlıdır ve sizin için iyi olan daha fazla iş parçacığınız yoksa oldukça hızlı bir şekilde tekrar edinebilirsiniz! - Alex Martelli
(IO ile karşılaştığım en büyük darboğazlar genellikle uygun arabellek değildir ve tekrarlanan "her bayt" sistem-IO çağrılarıdır. Diller arasında oldukça evrensel, bazıları daha iyi / varsayılan olarak gizler.) - user2864740
@AlexMartelli Bana inanmıyorsanız bu kodu çalıştırın: repl.it/f72 - Shashank
@Shashank Bunun çıktı tamponlaması kadar GIL ile ilgili olduğundan emin değilim. Her baskının sonunda (yeni hat sayesinde) 'etkileşimli modda' - en azından daha adil bir karşılaştırmanın doğrudan etkileşimli olmayan bir akışa yazacağı bir 'gömme' söz konusudur. (Konsola birçok satır yazmak, "düz C" de olsa, nispeten yavaştır.) Bkz. stackoverflow.com/questions/1716296 - user2864740
@ user2864740 Haklısınız, etkileşimli olmayan bir akıma yazarken ilk yöntemde performansta büyük bir artış var. Bununla birlikte, ikinci yol hala fark edilebilir bir marjla daha hızlıdır. - Shashank