Tutorial Material

Multithreading va multiprocessing

Share to
Python multithreading va multiprocessing

Zamonaviy dasturlashda parallelism va concurrency kabi atamalar ko'p uchraydi. Python'da bir vaqtning o'zida bir nechta ishni bajarishning ikki asosiy yo'li bor: multithreading va multiprocessing.

Qaysi birini tanlash vazifangiz turiga bog'liq: u I/O Boundmi yoki CPU Boundmi.

1. I/O Bound va CPU Bound

2. Multithreading (I/O Bound uchun)

Threading bitta process ichida bir nechta thread ishlatadi. Thread'lar xotirani bo'lishadi (shared memory).

Lekin Python (CPython) da GIL (Global Interpreter Lock) bor: u bir vaqtning o'zida ikki thread'ning bitta CPU core'da Python bytecode bajarishini cheklaydi. Shuning uchun Python multithreading CPU-bound ishlarni tezlashtirmaydi (hatto overhead sabab sekinlashishi ham mumkin).

Ammo I/O bound ishlar uchun multithreading juda foydali: bitta thread kutayotgan paytda (masalan web javobini), boshqasi ishlashi mumkin.

import threading
import time

def download_page(url):
    print(f"Start downloading {url}...")
    time.sleep(2) # Simulate network delay
    print(f"Finished downloading {url}")

start = time.time()

threads = []
urls = ["web1", "web2", "web3"]

for url in urls:
    t = threading.Thread(target=download_page, args=(url,))
    threads.append(t)
    t.start()

# Barcha thread'lar tugashini kutish
for t in threads:
    t.join()

end = time.time()
print(f"Umumiy vaqt: {end - start:.2f} soniya")
# Natija taxminan 2 soniya, 6 soniya emas!

3. Multiprocessing (CPU Bound uchun)

Multiprocessing alohida Python process'larni yaratadi. Har bir process'ning o'z Python interpreter'i va xotira maydoni bo'ladi. Bu GIL'ni chetlab o'tadi va multi-core CPU'dan maksimal foydalanishga imkon beradi.

Og'ir hisob-kitobli vazifalar uchun shuni ishlating.

import multiprocessing
import time

def heavy_square_calculation(number):
    print(f"Process {number} starts...")
    result = sum(i * i for i in range(10**7)) # Heavy calculation
    print(f"Process {number} finished.")
    return result

if __name__ == "__main__":
    start = time.time()

    # Turli CPU core'larda parallel ishlaydigan 2 ta process yaratish
    p1 = multiprocessing.Process(target=heavy_square_calculation, args=(1,))
    p2 = multiprocessing.Process(target=heavy_square_calculation, args=(2,))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    end = time.time()
    print(f"Total time: {end - start:.2f} seconds")

Eslatma: Windows'da multiprocessing ishlatganda asosiy kodni if __name__ == "__main__": bilan himoyalash kerak.

4. Concurrent Futures (zamonaviy usul)

Python concurrent.futures modulini beradi. U Threading va Multiprocessing uchun yuqori darajali va ishlatish oson interfeys.

from concurrent.futures import ThreadPoolExecutor
import time

def task(n):
    time.sleep(1)
    return f"Task {n} finished"

start = time.time()

with ThreadPoolExecutor(max_workers=3) as executor:
    results = executor.map(task, [1, 2, 3])

    for result in results:
        print(result)

print(f"Time: {time.time() - start:.2f} seconds")

Multiprocessing'ga o'tmoqchi bo'lsangiz ThreadPoolExecutor o'rniga ProcessPoolExecutor ishlating.

Xulosa

Xususiyat Multithreading Multiprocessing
Xotira Shared memory (umumiy) Separate memory (izolyatsiya)
Overhead Past Yuqori (process start vaqt oladi)
Mos vazifa I/O Bound (network, file) CPU Bound (hisob-kitob, data processing)
GIL GIL ta'sir qiladi GIL'dan holi