Sobes.tech
Middle

Python-da GIL (Global Interpreter Lock) nədir?

sobes.tech Süni İntellekt

AI-dan cavab

GIL (Qlobal Tərtib Tərcüməçisi Bağlantısı) CPython tərcüməçisində bir mexanizmdir və yalnız bir axın (thread) eyni zamanda icra oluna bilər. Hətta çox nüvəli prosessorlarda belə, GIL Python kodunun faktiki paralel icrasına imkan vermir.

GIL-in mövcud olmasının səbəbləri:

  • Yaddaş idarəsinin sadələşdirilməsi: GIL, axınlar üçün təhlükəsiz yaddaş idarəsini və tullantıların toplanmasını (istinadçı sayğacını) sadələşdirir. GIL olmasa, ümumi məlumat strukturlarını qorumaq üçün daha mürəkkəb və resurs tələb edən kilid mexanizmləri lazım olardı.
  • C kitabxanaları ilə uyğunluq: GIL, mövcud C kitabxanaları ilə inteqrasiyanı asanlaşdırır; bu kitabxanalar çox vaxt axın təhlükəsiz olmaya bilər.

GIL-in təsiri:

  • CPU-ya əsaslanan tapşırıqlarda paralelliyin məhdudlaşdırılması: CPU intensiv tapşırıqlar üçün, GIL dar boğaz olur, çünki çox nüvəli sistemlərdə belə, icra nüvələr arasında paralel deyil. Axınlar GIL sərbəst buraxılana qədər gözləməlidir.
  • I/O-ya əsaslanan tapşırıqlarda daha az təsir: Şəbəkə sorğuları və fayllarla işləmə kimi I/O intensiv tapşırıqlarda, GIL daha az kritikdir. I/O əməliyyatları zamanı, axın GIL-i sərbəst buraxır və digər axınların işləməsinə imkan verir.

GIL-dən yayınma yolları:

  • Çox prosessli (multiprocessing): Axınlar yerinə, müstəqil proseslər istifadə olunur. Hər prosesin öz Python tərcüməçisi və ona görə də, öz GIL-i var. Proseslər müxtəlif nüvələrdə paralel işləyə bilər.
  • Asinxron proqramlaşdırma (asyncio): Bir axında asinxron giriş/çıxış modelindən istifadə edir. Bir çox axın yaratmaq yerinə, I/O gözləmə zamanı tapşırıqlar arasında keçid edir. GIL bu prosesə çox təsir etmir, çünki CPU ilə əlaqəli tapşırıqlar paralel icra edilmir.
  • C/C++ kitabxanaları: C və ya C++ ilə yazılmış kod hissələri, GIL-i saxlamadan əməliyyatları yerinə yetirə bilər; bu, bu əməliyyatlar zamanı GIL-in sərbəst buraxılmasını təmin edir. NumPy və SciPy kimi məşhur kitabxanalar, bu üsuldan istifadə edir, yüksək performanslı hesablamalar üçün.
# CPU-ya əsaslanan tapşırıqda GIL-in təsirini nümunə edən nümunə
import threading
import time

def cpu_bound_task():
    count = 0
    for i in range(10**7):
        count += 1

# CPU-ya əsaslanan tapşırıq üçün iki axın yaradılır
t1 = threading.Thread(target=cpu_bound_task)
t2 = threading.Thread(target=cpu_bound_task)

start_time = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end_time = time.time()

print(f"CPU-ya əsaslanan tapşırıqda GIL-in təsiri ilə icra vaxtı: {end_time - start_time:.2f} saniyə") # Vaxt təxminən iki dəfə çox olacaq, GIL səbəbindən

# I/O-ya əsaslanan tapşırıq nümunəsi, burada GIL daha az görünür
import threading
import time

def io_bound_task():
    time.sleep(1) # I/O gözləmə simulasyonu

# I/O-ya əsaslanan tapşırıq üçün iki axın yaradılır
t1 = threading.Thread(target=io_bound_task)
t2 = threading.Thread(target=io_bound_task)

start_time = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end_time = time.time()

print(f"GIL-in daha az təsiri ilə I/O-ya əsaslanan tapşırıq vaxtı: {end_time - start_time:.2f} saniyə") # Vaxt təxminən 1 saniyə olacaq, çünki axınlar sleep zamanı GIL-i sərbəst buraxır