Mam nadzieję, że ktoś może udzielić pewnego wglądu w to, co zasadniczo różni się w wirtualnej maszynie Java, która pozwala jej ładnie implementować wątki bez potrzeby globalnej blokady interpretera (GIL), podczas gdy Python wymaga takiego zła.
Mam nadzieję, że ktoś może udzielić pewnego wglądu w to, co zasadniczo różni się w wirtualnej maszynie Java, która pozwala jej ładnie implementować wątki bez potrzeby globalnej blokady interpretera (GIL), podczas gdy Python wymaga takiego zła.
Odpowiedzi:
Python (język) nie potrzebuje GIL (dlatego można go doskonale zaimplementować na JVM [Jython] i .NET [IronPython], a te implementacje swobodnie wielowątkowe). CPython (popularna implementacja) zawsze używał GIL dla łatwości kodowania (zwłaszcza kodowania mechanizmów zbierania śmieci) i integracji nie-bezpiecznych dla wątków bibliotek kodowanych w C (kiedyś było ich mnóstwo; -).
Projekt Unladen Swallow , oprócz innych ambitnych celów, planuje maszynę wirtualną wolną od GIL dla Pythona - cytując tę witrynę: „Ponadto zamierzamy usunąć GIL i naprawić stan wielowątkowości w Pythonie. Uważamy, że jest to możliwe dzięki wdrożeniu bardziej wyrafinowanego systemu GC, czegoś w rodzaju Recycler firmy IBM (Bacon et al, 2001). "
JVM (przynajmniej hotspot) ma podobną koncepcję do "GIL", jest po prostu znacznie drobniejszy w swojej szczegółowości blokad, większość pochodzi z GC w hotspotach, które są bardziej zaawansowane.
W CPythonie jest to jedna duża blokada (prawdopodobnie nie do końca prawda, ale wystarczająco dobra ze względu na argumenty), w JVM jest bardziej rozpowszechniona z różnymi koncepcjami w zależności od tego, gdzie jest używana.
Spójrz na przykład na vm / runtime / safepoint.hpp w kodzie hotspotu, który jest efektywną barierą. W bezpiecznym punkcie cała maszyna wirtualna zatrzymała się w odniesieniu do kodu java, podobnie jak maszyna wirtualna Pythona zatrzymuje się na GIL.
W świecie Javy takie zdarzenia wstrzymania maszyny wirtualnej są znane jako „stop-the-world”, w tych miejscach tylko kod natywny powiązany z określonymi kryteriami działa swobodnie, a reszta maszyny wirtualnej została zatrzymana.
Również brak zgrubnej blokady w Javie znacznie utrudnia pisanie JNI, ponieważ JVM daje mniej gwarancji dotyczących swojego środowiska dla wywołań FFI, co jest jedną z rzeczy, które cpython sprawia, że jest dość łatwa (chociaż nie tak łatwa jak używanie ctypów).
Poniżej znajduje się komentarz w tym poście na blogu http://www.grouplens.org/node/244 który wskazuje, dlaczego tak łatwo zrezygnować z GIL dla IronPython lub Jython, jest tak, że CPython używa liczenia referencji, podczas gdy pozostałe 2 maszyny wirtualne mają odśmiecanie pamięci.
Nie rozumiem dokładnej mechaniki, dlaczego tak jest, ale brzmi to jak wiarygodny powód.
W tym linku mają następujące wyjaśnienie:
... "Części Interpretera nie są bezpieczne dla wątków, chociaż głównie dlatego, że uczynienie ich wszystkich bezpiecznymi wątkami przez masowe użycie blokad spowolniłoby bardzo pracę jednowątkową ( źródło ). Wydaje się, że jest to związane z wyrzucaniem elementów bezużytecznych w CPython korzystającym z liczenia odwołań (JVM a CLR nie, i dlatego nie ma potrzeby blokowania / zwalniania liczby referencji za każdym razem). Ale nawet gdyby ktoś wymyślił akceptowalne rozwiązanie i wdrożył je, biblioteki innych firm nadal miałyby te same problemy ”.
Pythonowi brakuje jit / aot, a ramy czasowe, w których został napisany na procesorach wielowątkowych, nie istniały. Alternatywnie możesz ponownie skompilować wszystko w języku Julia lang, któremu brakuje GIL, i przyspieszyć działanie kodu Pythona. Jython jest do bani, wolniejszy niż Cpython i Java. Jeśli chcesz pozostać przy Pythonie, rozważ użycie równoległych wtyczek, nie uzyskasz natychmiastowego przyspieszenia, ale możesz wykonać programowanie równoległe za pomocą odpowiedniej wtyczki.