Cuprins
Recomandări cheie
- Concurența și paralelismul sunt principii fundamentale ale executării sarcinilor în calcul, fiecare având caracteristicile sale distincte.
- Concurența permite utilizarea eficientă a resurselor și o capacitate de răspuns îmbunătățită a aplicațiilor, în timp ce paralelismul este crucial pentru performanță și scalabilitate optime.
- Python oferă opțiuni pentru gestionarea concurenței, cum ar fi threading și programare asincronă cu asyncio, precum și paralelism folosind modulul de multiprocesare.
Concurența și paralelismul sunt două tehnici care vă permit să rulați mai multe programe simultan. Python are mai multe opțiuni pentru gestionarea sarcinilor concomitent și în paralel, ceea ce poate fi confuz.
Explorați instrumentele și bibliotecile disponibile pentru implementarea corectă a concurenței și paralelismului în Python și a modului în care acestea diferă.
Înțelegerea concurenței și paralelismului
Concurența și paralelismul se referă la două principii fundamentale ale executării sarcinilor în calcul. Fiecare are caracteristicile sale distincte.
Importanța concurenței și a paralelismului
Necesitatea concurenței și paralelismului în calcul nu poate fi exagerată. Iată de ce sunt importante aceste tehnici:
Concurență în Python
Puteți obține concurență în Python folosind threading și programare asincronă cu biblioteca asyncio.
Threading în Python
Threadingul este un mecanism de concurență Python care vă permite să creați și să gestionați sarcini într-un singur proces. Threadurile sunt potrivite pentru anumite tipuri de sarcini, în special cele care sunt legate de I/O și pot beneficia de execuția concomitentă.
Modulul de threading al lui Python oferă o interfață de nivel înalt pentru crearea și gestionarea thread-urilor. În timp ce GIL (Global Interpreter Lock) limitează firele de execuție în termeni de paralelism real, ele pot totuși să obțină concurență prin intercalarea eficientă a sarcinilor.
Codul de mai jos arată un exemplu de implementare a concurenței folosind fire. Utilizează biblioteca de solicitări Python pentru a trimite o solicitare HTTP, o sarcină comună de blocare a I/O. De asemenea, utilizează modulul de timp pentru a calcula timpul de execuție.
import requests
import time
import threadingurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]
def download_url(url):
response = requests.get(url)
print(f"Downloaded {url} - Status Code: {response.status_code}")
start_time = time.time()for url in urls:
download_url(url)end_time = time.time()
print(f"Sequential download took {end_time - start_time:.2f} seconds\n")
start_time = time.time()
threads = []for url in urls:
thread = threading.Thread(target=download_url, args=(url,))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()end_time = time.time()
print(f"Threaded download took {end_time - start_time:.2f} seconds")
Rulând acest program, ar trebui să vedeți cât de mai rapide sunt cererile threaded decât cererile secvențiale. Deși diferența este doar o fracțiune de secundă, obțineți o idee clară a îmbunătățirii performanței atunci când utilizați fire pentru activități legate de I/O.
Programare asincronă cu Asyncio
asincron oferă o buclă de evenimente care gestionează sarcini asincrone numite coroutine. Coroutinele sunt funcții pe care le puteți întrerupe și relua, făcându-le ideale pentru sarcini legate de I/O. Biblioteca este utilă în special pentru scenariile în care sarcinile implică așteptarea resurselor externe, cum ar fi solicitările de rețea.
Puteți modifica exemplul anterior de trimitere a cererii pentru a lucra cu asyncio:
import asyncio
import aiohttp
import timeurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]
async def download_url(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
content = await response.text()
print(f"Downloaded {url} - Status Code: {response.status}")
async def main():
tasks = [download_url(url) for url in urls]
await asyncio.gather(*tasks)start_time = time.time()
asyncio.run(main())end_time = time.time()
print(f"Asyncio download took {end_time - start_time:.2f} seconds")
Folosind codul, puteți descărca pagini web simultan folosind asyncio și puteți profita de operațiunile I/O asincrone. Acest lucru poate fi mai eficient decât threading-ul pentru sarcini legate de I/O.
Paralelism în Python
Puteți implementa paralelismul folosind Modulul de multiprocesare al lui Pythoncare vă permite să profitați din plin de procesoarele multicore.
Multiprocesare în Python
Modulul de multiprocesare al lui Python oferă o modalitate de a realiza paralelismul prin crearea de procese separate, fiecare cu propriul interpret Python și spațiu de memorie. Acest lucru ocolește în mod eficient Blocarea globală a interpretului (GIL), făcându-l potrivit pentru sarcini legate de CPU.
import requests
import multiprocessing
import timeurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]
def download_url(url):
response = requests.get(url)
print(f"Downloaded {url} - Status Code: {response.status_code}")def main():
num_processes = len(urls)
pool = multiprocessing.Pool(processes=num_processes)start_time = time.time()
pool.map(download_url, urls)
end_time = time.time()
pool.close()
pool.join()print(f"Multiprocessing download took {end_time-start_time:.2f} seconds")
main()
În acest exemplu, multiprocesarea generează mai multe procese, permițând funcției download_url să ruleze în paralel.
Când să folosiți concurența sau paralelismul
Alegerea între concurență și paralelism depinde de natura sarcinilor dvs. și de resursele hardware disponibile.
Puteți utiliza concurența atunci când aveți de-a face cu sarcini legate de I/O, cum ar fi citirea și scrierea în fișiere sau efectuarea de solicitări de rețea și atunci când constrângerile de memorie sunt o problemă.
Utilizați multiprocesarea atunci când aveți sarcini legate de CPU care pot beneficia de un paralelism real și atunci când aveți o izolare robustă între sarcini, unde eșecul unei sarcini nu ar trebui să le afecteze pe altele.
Profită de concurență și paralelism
Paralelismul și concurența sunt modalități eficiente de îmbunătățire a capacității de răspuns și a performanței codului dvs. Python. Este important să înțelegeți diferențele dintre aceste concepte și să alegeți cea mai eficientă strategie.
Python oferă instrumentele și modulele de care aveți nevoie pentru a vă face codul mai eficient prin concurență sau paralelism, indiferent dacă lucrați cu procese legate de CPU sau legate de I/O.