CodeGym /Kursy /Python SELF PL /Ominięcie GIL

Ominięcie GIL

Python SELF PL
Poziom 26 , Lekcja 4
Dostępny

11.1 Global Interpreter Lock

Global Interpreter Lock (GIL) to mechanizm w interpreterze CPython, który zapewnia, że tylko jeden wątek wykonuje bytecode Pythona w danym czasie. GIL zapobiega równoległemu wykonywaniu wątków, co może negatywnie wpływać na wydajność programów wielowątkowych, szczególnie na procesorach wielordzeniowych.

Przyczyny istnienia GIL

Uproszczenie zarządzania pamięcią: GIL upraszcza zarządzanie pamięcią i zbieranie śmieci, dzięki czemu Python jest łatwiejszy do implementacji.

Bezpieczeństwo wątków: GIL zapobiega stanom wyścigu, czyniąc wykonywanie kodu bezpiecznym dla wątków bez konieczności używania blokad.

Problemy spowodowane GIL

Ograniczona wydajność: Programy wielowątkowe wykonujące intensywne obliczenia nie mogą w pełni wykorzystać zalet procesorów wielordzeniowych ze względu na ograniczenia GIL.

Zniekształcenie wydajności: Programy, które intensywnie korzystają z wątków do wykonywania zadań, mogą napotkać pogorszenie wydajności z powodu przełączania kontekstu między wątkami.

Aktualnie istnieją 4 główne sposoby „ominięcia GIL”:

11.2 Wykorzystanie wieloprocesowości (multiprocessing)

Moduł multiprocessing pozwala tworzyć procesy, które działają równolegle i nie są ograniczone przez GIL, ponieważ każdy proces ma własny interpreter Pythona i pamięć.

Przykład:


import multiprocessing

def worker(num):
    print(f'Worker: {num}')
            
def main():
    processes = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()
            
    for p in processes:
        p.join()
            
main()

11.3 Programowanie asynchroniczne

Programowanie asynchroniczne z użyciem asyncio pozwala wykonywać zadania równolegle, nie blokując głównego wątku. Chociaż nie omija GIL w dosłownym znaczeniu, pozwala efektywnie wykorzystać czas oczekiwania na wykonywanie innych zadań.

Przykład:


import asyncio

async def main():
    await asyncio.sleep(1)
    print('Hello')
            
asyncio.run(main())

11.4 Wykorzystanie bibliotek z własnym zarządzaniem wątkami

Niektóre biblioteki, takie jak NumPy i SciPy, są napisane w C i używają własnych mechanizmów zarządzania wątkami, co pozwala im omijać GIL i efektywnie wykorzystywać procesory wielordzeniowe do obliczeń.

To właśnie jest jedną z głównych przyczyn sukcesu Pythona, jakkolwiek by on nie był wolny. Wszystkie skomplikowane obliczenia są przepisane na języki C/C++ i wykonywane na wszystkich rdzeniach procesora, a nawet od razu na rdzeniach karty graficznej. A na współczesnych kartach graficznych są tysiące rdzeni.

Okazuje się, że nie ma znaczenia, jak szybki czy wolny jest język, jeśli wszystkie wymagające obliczenia są wykonywane przez zewnętrzne biblioteki lub całkowicie przeniesione do zdalnych centrów danych.

11.5 Wykonywanie obliczeń poza interpretem Pythona

Użycie rozszerzeń w C/C++ lub innych językach, które mogą wykonywać obliczenia poza interpretem Pythona i następnie zwracać wynik. To pozwala uniknąć blokady GIL podczas wykonywania intensywnych obliczeń.

Przykład użycia Cython:


# example.pyx

def compute(int n):
    cdef int i, result = 0
    for i in range(n):
        result += i
    return result

Kompilacja i użycie:


cythonize -i example.pyx

import example
print(example.compute(1000000))
1
Опрос
Asynchroniczność,  26 уровень,  4 лекция
недоступен
Asynchroniczność
Asynchroniczność
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION