Paralleeltöötlus Pythonis: mitmelõimelisus, mitmeprotsessiline töö ja asyncio

1. Sissejuhatus

Paralleeltöötluse tähtsus Pythonis

Python on lihtne ja kasutajasõbralik programmeerimiskeel, mida kasutatakse laialdaselt erinevates valdkondades. Kuid keerukate andmetöötluste või arvutuste puhul võib Pythoni töötlemiskiirus olla väljakutse. Selle lahendamiseks mängib olulist rolli “paralleeltöötlus”, mis võimaldab mitut ülesannet samaaegselt käivitada. Käesolevas artiklis tutvustame, kuidas Pythonis paralleeltöötlust rakendada – alustades põhimõtetest kuni konkreetsete kasutusjuhtumiteni.

2. Paralleeltöötluse meetodid Pythonis

Peamised paralleeltöötluse viisid

Pythonis on mitmeid võimalusi paralleeltöötluse rakendamiseks. Kõige olulisemad neist on järgmised kolm:

  1. Mitmelõimelisus (threading moodul)
    Mitme lõime abil saab ülesandeid korraga täita, kuid Pythoni GIL (Global Interpreter Lock) tõttu on mõju CPU-intensiivsetel ülesannetel piiratud.
  2. Mitmeprotsessiline töötlus (multiprocessing moodul)
    Kuna iga protsess omab iseseisvat mäluruumi, ei mõjuta seda GIL ning võimalik on tõeline paralleeltöötlus. Sobib suuremahuliste andmetöötluste ja raskete arvutuste jaoks.
  3. Asünkroonne töötlus (asyncio moodul)
    Asünkroonne töötlus on efektiivne I/O-intensiivsete ülesannete (näiteks võrgusuhtlus või failitoimingud) puhul. See võimaldab ootamise ajal teisi ülesandeid tõhusalt edasi viia.

3. Mitmeprotsessiline vs Mitmelõimeline töötlus

GIL (Global Interpreter Lock) mõju

Pythonis on mehhanism nimega GIL, mis võimaldab korraga töötada ainult ühel lõimel. See tähendab, et CPU-intensiivsete ülesannete puhul ei paranda lõimede lisamine jõudlust. Seetõttu on lõimepõhine paralleeltöötlus kasulik vaid I/O-intensiivsete ülesannete puhul.

Mitmelõimelisuse eelised ja piirangud

Lõimed on kerged ja sobivad I/O-intensiivseteks ülesanneteks (failide töötlemine, võrguoperatsioonid jne). Kuid GIL-i tõttu ei saa kasutada täielikult kõiki CPU südamikke, mistõttu see pole optimaalne CPU-intensiivsete tööde jaoks.

“`python
import threading
import time

def worker(num):
print(f”Worker {num} starting”)
time.sleep(2)
print(f”Worker {num} finished”)

threads = [] for i in range(5):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()

for t in threads:
t.join()
“`

See kood käivitab korraga 5 lõime, millest igaüks töötab 2 sekundit ja lõpetab. Mitmelõimelisuse abil saab näha, kuidas ülesanded toimuvad paralleelselt.

Mitmeprotsessilise töötluse eelised

Mitmeprotsessiline töötlus väldib GIL-i piiranguid. Iga protsess töötab eraldi mäluruumis ja saab kasutada kõiki CPU südamikke. See on eriti kasulik suurte arvutuste ja andmemahukate ülesannete puhul.

“`python
from multiprocessing import Process
import time

def worker(num):
print(f”Worker {num} starting”)
time.sleep(2)
print(f”Worker {num} finished”)

if __name__ == ‘__main__’:
processes = [] for i in range(5):
p = Process(target=worker, args=(i,))
processes.append(p)
p.start()

for p in processes:
p.join()
“`

Selles näites töötab 5 protsessi paralleelselt ja igaüks täidab oma ülesande. join() meetod ootab iga protsessi lõpetamist enne, kui programm edasi liigub.

4. Kuidas Pythonis paralleeltöötlust rakendada

multiprocessing mooduli kasutamine

multiprocessing moodul võimaldab hallata mitut protsessi tõhusalt. Allpool on näide protsesside basseini kasutamisest ülesannete paralleelseks täitmiseks.

“`python
from multiprocessing import Pool

def square(x):
return x * x

if __name__ == ‘__main__’:
with Pool(4) as p:
result = p.map(square, [1, 2, 3, 4, 5])
print(result)
“`

Selles koodis töötab korraga 4 protsessi, millest igaüks arvutab loendi elemendi ruudu. Tulemused tagastatakse loendina.

RUNTEQ(ランテック)|超実戦型エンジニア育成スクール

5. Asünkroonne töötlus ja selle kasutusvaldkonnad

Asünkroonne töötlus asyncio mooduliga

asyncio sobib eriti hästi ülesannetele, kus esineb I/O ooteaegu. See võimaldab ooteaegadel käivitada teisi ülesandeid.

“`python
import asyncio

async def worker(num):
print(f’Worker {num} starting’)
await asyncio.sleep(1)
print(f’Worker {num} finished’)

async def main():
tasks = [worker(i) for i in range(5)] await asyncio.gather(*tasks)

asyncio.run(main())
“`

See kood käivitab korraga 5 ülesannet. await märksõna abil saab töödelda mitut ülesannet paralleelselt.

6. Paralleeltöötluse jõudluse optimeerimine

Joblibi kasutamine

Joblib on teek, mis aitab optimeerida raskeid arvutusi ja masinõppe mudeleid. Näide Joblibi kasutamisest paralleeltöötluses:

“`python
from joblib import Parallel, delayed

def heavy_task(n):
return n ** 2

results = Parallel(n_jobs=4)(delayed(heavy_task)(i) for i in range(10))
print(results)
“`

n_jobs parameeter määrab protsesside arvu. Selles näites arvutatakse tulemused 4 protsessiga paralleelselt.

7. Praktilised rakendused

Andmetöötlus ja veebiskreipimine

Paralleeltöötlus on eriti kasulik andmetöötluses ja veebiskreipimisel. Näiteks veebilehtede samaaegne allalaadimine mitme lõime või asünkroonse töötluse abil lühendab tööaega oluliselt. Samuti masinõppe treeningutel või andmete eeltöötlemisel aitavad multiprocessing ja Joblib tõsta jõudlust.

8. Kokkuvõte

Paralleeltöötlus on oluline tehnika Pythoni jõudluse suurendamiseks. Õigesti kasutades mooduleid nagu threading, multiprocessing, asyncio ja Joblib, saab oluliselt parandada erinevate ülesannete täitmise efektiivsust. Kasuta neid meetodeid oma projektides, et saavutada paremaid tulemusi.

RUNTEQ(ランテック)|超実戦型エンジニア育成スクール