Sobes.tech
Middle

Python'da GIL (Global Interpreter Lock) nima?

sobes.tech AI

AIdan javob

GIL (Global Interpreter Lock) — bu mexanizm CPython interpretatorida, faqat bitta oqim (thread) bir vaqtning o'zida bajarilishiga imkon beradi. Hatto ko'p yadroli protsessorlarda ham, GIL Python-kodining haqiqiy parallel bajarilishini ta'minlamaydi.

GIL mavjud bo'lishining sabablari:

  • Xotira boshqaruvini soddalashtirish: GIL, oqimlar uchun xavfsiz xotira boshqaruvi va chiqindilarni yig'ish (referenslar hisoblagichi)ni soddalashtiradi. GIL bo'lmasa, umumiy ma'lumot tuzilmalarini himoya qilish uchun yanada murakkab va resurslarni ko'proq talab qiladigan blokirovka mexanizmlari kerak bo'lardi.
  • C kutubxonalar bilan moslik: GIL, mavjud C kutubxonalar bilan integratsiyani osonlashtiradi, ular oqim xavfsiz bo'lmasligi mumkin.

GIL ta'siri:

  • CPU-ga bog'liq vazifalarda parallelizm cheklovlari: CPU intensiv vazifalar uchun, GIL muammoga aylanishi mumkin, chunki ko'p yadroli tizimlarda ham, bajarilish yadrolar o'rtasida parallel emas. Oqimlar GIL bo'shatilishini kutadi.
  • I/O-ga bog'liq vazifalarda kamroq ta'sir: Tarmoq so'rovlar yoki fayllar bilan ishlash kabi I/O intensiv vazifalarda, GIL kamroq muhim. I/O operatsiyalari davomida, oqim GILni bo'shatadi, boshqa oqimlar ishlashiga imkon beradi.

GILni chetlash usullari:

  • Ko'p jarayonli (multiprocessing): Oqimlar o'rniga, mustaqil jarayonlar ishlatiladi. Har bir jarayon o'z Python interpretatorining nusxasiga ega va shuning uchun, o'z GILga ham. Jarayonlar, turli yadroda parallel ishlashlari mumkin.
  • Asinxron dasturlash (asyncio): Bir oqimda asinxron kirish/chiqish modelidan foydalanadi. Bir nechta oqimlar o'rniga, I/O kutish vaqtida vazifalar o'rtasida o'tishni amalga oshiradi. GIL bu jarayonga juda ta'sir qilmaydi, chunki CPU bilan bog'liq vazifalar parallel bajarilmaydi.
  • C/C++ kutubxonalari: C yoki C++da yozilgan kod qismlari, GILni ushlab turmasdan, operatsiyalarni bajarishi mumkin, uni bajarish vaqtida bo'shatadi. NumPy va SciPy kabi mashhur kutubxonalar, bu usuldan foydalanadi, yuqori samarali hisoblashlar uchun.
# CPU-ga bog'liq vazifa uchun GIL ta'sirini misol qilish
import threading
import time

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

# CPU-ga bog'liq vazifani bajarish uchun ikki oqim yaratish
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-ga bog'liq vazifa bilan (GIL ta'siri): {end_time - start_time:.2f} sekund") # Vaqt taxminan ikki baravar ko'proq bo'ladi, GIL sababli

# I/O-ga bog'liq vazifa uchun GIL kamroq ta'sir qiladi
import threading
import time

def io_bound_task():
    time.sleep(1) # I/O kutish simulyatsiyasi

# I/O-ga bog'liq vazifa uchun ikki oqim yaratish
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"I/O-ga bog'liq vazifa bilan (GIL kamroq ta'sir qiladi): {end_time - start_time:.2f} sekund") # Vaqt taxminan 1 sekund bo'ladi, chunki oqimlar sleep vaqtida GILni bo'shatadi