Innholdsfortegnelse
Viktige takeaways
- Samtidighet og parallellitet er grunnleggende prinsipper for oppgaveutførelse i databehandling, der hver har sine distinkte egenskaper.
- Samtidig gir mulighet for effektiv ressursutnyttelse og forbedret respons for applikasjoner, mens parallellitet er avgjørende for optimal ytelse og skalerbarhet.
- Python gir alternativer for håndtering av samtidighet, for eksempel tråding og asynkron programmering med asyncio, samt parallellitet ved bruk av multiprosesseringsmodulen.
Samtidighet og parallellitet er to teknikker som lar deg kjøre flere programmer samtidig. Python har flere alternativer for å håndtere oppgaver samtidig og parallelt, noe som kan være forvirrende.
Utforsk verktøyene og bibliotekene som er tilgjengelige for riktig implementering av samtidighet og parallellitet i Python, og hvordan de er forskjellige.
Forstå samtidighet og parallellisme
Samtidighet og parallellisme refererer til to grunnleggende prinsipper for oppgaveutførelse i databehandling. Hver har sine distinkte egenskaper.
Viktigheten av samtidighet og parallellisme
Behovet for samtidighet og parallellitet i databehandling kan ikke overvurderes. Her er hvorfor disse teknikkene betyr noe:
Samtidighet i Python
Du kan oppnå samtidighet i Python ved å bruke tråding og asynkron programmering med asyncio-biblioteket.
Tråder i Python
Threading er en Python samtidighetsmekanisme som lar deg opprette og administrere oppgaver innenfor en enkelt prosess. Tråder er egnet for visse typer oppgaver, spesielt de som er I/O-bundet og kan dra nytte av samtidig utførelse.
Pythons trådmodul gir et grensesnitt på høyt nivå for å lage og administrere tråder. Mens GIL (Global Interpreter Lock) begrenser tråder når det gjelder ekte parallellitet, kan de fortsatt oppnå samtidighet ved å sammenflette oppgaver effektivt.
Koden nedenfor viser et eksempel på implementering av samtidighet ved bruk av tråder. Den bruker Python-forespørselsbiblioteket til å sende en HTTP-forespørsel, en vanlig I/O-blokkeringsoppgave. Den bruker også tidsmodulen til å beregne utførelsestid.
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")
Når du kjører dette programmet, bør du se hvor mye raskere de trådede forespørslene er enn de sekvensielle forespørslene. Selv om forskjellen bare er en brøkdel av et sekund, får du en klar følelse av ytelsesforbedringen når du bruker tråder for I/O-bundne oppgaver.
Asynkron programmering med Asyncio
asyncio gir en hendelsesløkke som administrerer asynkrone oppgaver kalt coroutines. Coroutines er funksjoner som du kan pause og gjenoppta, noe som gjør dem ideelle for I/O-bundne oppgaver. Biblioteket er spesielt nyttig for scenarier der oppgaver innebærer å vente på eksterne ressurser, for eksempel nettverksforespørsler.
Du kan endre det forrige eksemplet på forespørselssending for å fungere med 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")
Ved å bruke koden kan du laste ned nettsider samtidig ved å bruke asyncio og dra nytte av asynkrone I/O-operasjoner. Dette kan være mer effektivt enn tråding for I/O-bundne oppgaver.
Parallellisme i Python
Du kan implementere parallellitet ved å bruke Pythons multiprosesseringsmodulsom lar deg dra full nytte av flerkjerneprosessorer.
Multiprosessering i Python
Pythons multiprosesseringsmodul gir en måte å oppnå parallellitet ved å lage separate prosesser, hver med sin egen Python-tolk og minneplass. Dette omgår effektivt Global Interpreter Lock (GIL), noe som gjør den egnet for CPU-bundne oppgaver.
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()
I dette eksemplet skaper multiprosessering flere prosesser, slik at download_url-funksjonen kan kjøres parallelt.
Når du skal bruke samtidighet eller parallellisme
Valget mellom samtidighet og parallellitet avhenger av arten av oppgavene dine og de tilgjengelige maskinvareressursene.
Du kan bruke samtidighet når du håndterer I/O-bundne oppgaver, for eksempel lesing og skriving til filer eller forespørsler om nettverk, og når minnebegrensninger er et problem.
Bruk multiprosessering når du har CPU-bundne oppgaver som kan dra nytte av ekte parallellitet og når du har robust isolasjon mellom oppgaver, der en oppgaves feil ikke bør påvirke andre.
Dra nytte av samtidighet og parallellisme
Parallellisme og samtidighet er effektive måter å forbedre responsen og ytelsen til Python-koden din. Det er viktig å forstå forskjellene mellom disse konseptene og velge den mest effektive strategien.
Python tilbyr verktøyene og modulene du trenger for å gjøre koden din mer effektiv gjennom samtidighet eller parallellitet, uavhengig av om du jobber med CPU-bundne eller I/O-bundne prosesser.