Utilizați aceste tehnici pentru a rula codul simultan și pentru a oferi o experiență mai fluidă pentru utilizator.
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.
- Concurență este capacitatea unui program de a gestiona mai multe sarcini în același timp fără a le executa neapărat exact în același timp. Se învârte în jurul ideii de intercalare a sarcinilor, comutând între ele într-un mod care pare simultan.
- Paralelism, pe de altă parte, implică executarea mai multor sarcini în mod real în paralel. De obicei profită de mai multe nuclee CPU sau procesoare. Paralelismul realizează o execuție simultană reală, permițându-vă să efectuați sarcini mai rapid și este potrivit pentru operațiuni intensive din punct de vedere computațional.
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:
- Utilizarea resurselor: Concurența permite utilizarea eficientă a resurselor sistemului, asigurându-se că sarcinile progresează în mod activ, mai degrabă decât să aștepte cu liniște resurse externe.
- Receptivitatea: Concurența poate îmbunătăți capacitatea de răspuns a aplicațiilor, în special în scenariile care implică interfețe de utilizator sau servere web.
- Performanţă: Paralelismul este esențial pentru obținerea performanțelor optime, în special în sarcini legate de CPU, cum ar fi calcule complexe, procesarea datelor și simulări.
- Scalabilitate: Atât concurența, cât și paralelismul sunt esențiale pentru construirea de sisteme scalabile.
- Pregătire pentru viitor: Pe măsură ce tendințele hardware continuă să favorizeze procesoarele multicore, capacitatea de a valorifica paralelismul va deveni din ce în ce mai necesară.
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ă.
Al lui Python filetat modul 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, folosește modul 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',
]# function to request a URL
defdownload_url(url):
response = requests.get(url)
print(f"Downloaded {url} - Status Code: {response.status_code}")# Execute without threads and measure execution time
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")# Execute with threads, resetting the time to measure new execution time
start_time = time.time()
threads = []for url in urls:
thread = threading.Thread(target=download_url, args=(url,))
thread.start()
threads.append(thread)# Wait for all threads to complete
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 el asincron:
import asyncio
import aiohttp
import timeurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]# asynchronous function to request URL
asyncdefdownload_url(url):
asyncwith aiohttp.ClientSession() as session:
asyncwith session.get(url) as response:
content = await response.text()
print(f"Downloaded {url} - Status Code: {response.status}")# Main asynchronous function
asyncdefmain():
# Create a list of tasks to download each URL concurrently
tasks = [download_url(url) for url in urls]# Gather and execute the tasks concurrently
await asyncio.gather(*tasks)start_time = time.time()
# Run the main asynchronous function
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 asincron și profitați 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 Al lui Python multiprocesare modul, care vă permite să profitați din plin de procesoarele multicore.
Multiprocesare în Python
Al lui Python multiprocesare modulul 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',
]# function to request a URL
defdownload_url(url):
response = requests.get(url)
print(f"Downloaded {url} - Status Code: {response.status_code}")defmain():
# Create a multiprocessing pool with a specified number of processes
num_processes = len(urls)
pool = multiprocessing.Pool(processes=num_processes)start_time = time.time()
pool.map(download_url, urls)
end_time = time.time()# Close the pool and wait for all processes to finish
pool.close()
pool.join()print(f"Multiprocessing download took {end_time-start_time:.2f} seconds")
main()
În acest exemplu, multiprocesare generează mai multe procese, permițând download_url funcția 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.