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 umumiy xotirani baham ko'radi (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, veb 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 shu yondashuvni tanlang.

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"Umumiy vaqt: {end - start:.2f} soniya")

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, 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.

5. Thread xavfsizligi va Lock'lar

Thread'lar xotirani baham ko'rgani uchun, ikkita thread bir vaqtda bitta o'zgaruvchini yangilasa, uni buzishi mumkin — bu race condition. Lock bir vaqtning o'zida faqat bitta thread kritik qismga kirishini ta'minlaydi.

import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(100_000):
        with lock:          # bir vaqtda faqat bitta thread yangilaydi
            counter += 1

threads = [threading.Thread(target=increment) for _ in range(2)]
for t in threads:
    t.start()
for t in threads:
    t.join()

print(counter)   # 200000  (lock tufayli to'g'ri)

Lock bo'lmasa, oxirgi qiymat ko'pincha 200000 dan kam bo'lardi, chunki ikkala thread ham yozishdan oldin bir xil eski qiymatni o'qishi mumkin.

Eslatma: I/O bilan bog'liq ishda bir tredli concurrency uchun asyncio ko'pincha thread'lardan ko'ra mosroq. Async / Await darsiga qarang.

Xulosa

Xususiyat Multithreading Multiprocessing
Xotira Umumiy xotira (shared memory) Alohida xotira (separate memory)
Overhead Past Yuqori (process boshlanishi vaqt oladi)
Mos vazifa I/O Bound (tarmoq, fayl) CPU Bound (hisob-kitob, ma'lumot qayta ishlash)
GIL GIL ta'sir qiladi GIL'dan holi