Tråding reduserer utførelsestiden til et program betydelig. Lær hvordan du implementerer tråder i Python.
Gjennomføringstid er et av de vanlige målene for effektiviteten til et program. Jo raskere utførelsestiden er, desto bedre er programmet. Tråding er en teknikk som lar et program utføre flere oppgaver eller prosesser samtidig.
Du vil lære hvordan du bruker Python innebygd tråding modul og samtidige.funksjoner modul. Begge disse modulene tilbyr enkle måter å opprette og administrere tråder på
Viktigheten av tråding
Tråding reduserer tiden et program tar å fullføre en jobb. Hvis jobben inneholder flere uavhengige oppgaver, kan du bruke tråder til å kjøre oppgavene samtidig, noe som reduserer programmets ventetid for en oppgave å fullføre før du går videre til den neste.
For eksempel et program som laster ned flere bildefiler fra internett. Dette programmet kan bruke tråding for å laste ned filene parallelt i stedet for én om gangen. Dette eliminerer tiden programmet må vente på at nedlastingsprosessen for én fil skal fullføres før du går videre til den neste.
Innledende program før tråding
Funksjonen i følgende program representerer en oppgave. Oppgaven er å pause utførelsen av programmet i ett sekund. Programmet kaller funksjonen to ganger, og lager derfor to oppgaver. Den beregner deretter tiden det tok for hele programmet å kjøre og viser det deretter på skjermen.
import tid
start_time = time.perf_counter()
defpause():
skrive ut("Sover 1 sekund...")
tid.søvn(1)
skrive ut("Sov ferdig...")
pause()
pause()
finish_time = time.perf_counter()
skrive ut(f'Ferdig i {runde (sluttid - starttid, 2)} sekund(er)')
Utdataene viser at programmet tok 2,01 sekunder å kjøre. Hver oppgave tok ett sekund og resten av koden tok 0,01 sekunder å utføre.
Du kan bruke tråding for å utføre begge oppgavene samtidig. Dette vil ta begge oppgavene ett sekund å utføre.
Implementering av tråding ved hjelp av gjengemodulen
For å endre den opprinnelige koden for å implementere tråding, importer tråding modul. Lag to tråder, tråd_1 og tråd_2 bruker Tråd klasse. Ring start metode på hver tråd for å starte utførelsen. Ring bli med metode på hver tråd for å vente på at de blir utført før resten av programmet kjøres.
import tid
import tråding
start_time = time.perf_counter()defpause():
skrive ut("Sover 1 sekund...")
tid.søvn(1)
skrive ut("Sov ferdig...")thread_1 = tråding. Tråd (mål=pause)
thread_2 = tråding. Tråd (mål=pause)thread_1.start()
thread_2.start()thread_1.join()
thread_2.join()
finish_time = time.perf_counter()
skrive ut(f'Ferdig i {runde (sluttid - starttid, 2)} sekund(er)')
Programmet vil kjøre begge trådene samtidig. Dette vil redusere tiden det tar å utføre begge oppgavene.
Utdataene viser at tiden det tar å kjøre de samme oppgavene er rundt ett sekund. Dette er halvparten av tiden det første programmet tok.
Implementere tråding ved å bruke concurrent.futures-modulen
Python 3.2 så introduksjonen av concurrent.futures modul. Denne modulen gir et grensesnitt på høyt nivå for å utføre asynkrone oppgaver ved hjelp av tråder. Det gir en enklere måte å utføre oppgaver parallelt på.
For å endre det opprinnelige programmet til å bruke tråding, importer modulen Concurrent.features. Bruke ThreadPoolExecutor klasse fra concurrent.futures-modulen for å lage en pool av tråder. Send inn pause funksjon til bassenget to ganger. De sende inn metoden returnerer en framtid objekt som representerer resultatet av funksjonskallet.
Iterere over futures og skriv ut resultatene ved hjelp av resultat metode.
import tid
import concurrent.futuresstart_time = time.perf_counter()
defpause():
skrive ut("Sover 1 sekund...")
tid.søvn(1)
komme tilbake"Sov ferdig..."med concurrent.futures. ThreadPoolExecutor() som eksekutor:
resultater = [executor.submit (pause) til _ i område(2)]
til f i concurrent.futures.as_completed (resultater):
print (f.result())finish_time = time.perf_counter()
skrive ut(f'Ferdig i {runde (sluttid - starttid, 2)} sekund(er)')
Concurrent.features-modulen tar seg av å starte og bli med i trådene for deg. Dette gjør koden din renere.
Utgangen er identisk med gjengemodulen. Gjengemodulen er nyttig for enkle tilfeller der du trenger å kjøre noen få tråder parallelt. På den annen side er concurrent.futures-modulen nyttig for mer komplekse tilfeller der du må kjøre mange oppgaver samtidig.
Bruk av tråding i et virkelighetsscenario
Bruk av tråder for å kjøre programmet ovenfor reduserte tiden med ett sekund. I den virkelige verden sparer tråder mer tid. Lag et program som laster ned bilder fra internett. Start med skape et nytt virtuelt miljø. Kjør følgende kommando i terminalen for å installere forespørsler bibliotek:
pip-installasjonsforespørsler
Forespørselsbiblioteket lar deg sende HTTP-forespørsler. Importer forespørselsbiblioteket og tidsbiblioteket.
import forespørsler
import tid
Lag en liste over URL-er til bildene du vil laste ned. La dem være minst ti, slik at du kan merke en betydelig forskjell når du implementerer gjenger.
img_urls = [
' https://images.unsplash.com/photo-1524429656589-6633a470097c',
' https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
' https://images.unsplash.com/photo-1564135624576-c5c88640f235',
' https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
' https://images.unsplash.com/photo-1522364723953-452d3431c267',
' https://images.unsplash.com/photo-1513938709626-033611b8cc03',
' https://images.unsplash.com/photo-1507143550189-fed454f93097',
' https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
' https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
' https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
' https://images.unsplash.com/photo-1516972810927-80185027ca84',
' https://images.unsplash.com/photo-1550439062-609e1531270e',
]
Sløyfe over listen av URL-er som laster ned hvert bilde til den samme mappen som inneholder prosjektet ditt. Vis tiden det tar å laste ned bildene ved å trekke slutttiden fra starttiden.
start_time = time.perf_counter()
til img_url i img_urls:
img_bytes = requests.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
med åpen (img_name, 'wb') som img_file:
img_file.write (img_bytes)
skrive ut(f'{img_name} ble lastet ned...')
finish_time = time.perf_counter()
skrive ut(f'Ferdig i {finish_time - start_time} sekunder')
Programmet tar rundt 22 sekunder å laste ned de 12 bildene. Det kan variere for deg ettersom tiden det tar å laste ned bildene også avhenger av hastigheten på Internett.
Endre programmet for å bruke tråding ved å bruke modulen Concurrent.features. I stedet for en loop, bruk en funksjon. Dette er funksjonen du vil overføre til eksekutor forekomst.
import forespørsler
import tid
import concurrent.futuresimg_urls = [
' https://images.unsplash.com/photo-1524429656589-6633a470097c',
' https://images.unsplash.com/photo-1530224264768-7ff8c1789d79',
' https://images.unsplash.com/photo-1564135624576-c5c88640f235',
' https://images.unsplash.com/photo-1541698444083-023c97d3f4b6',
' https://images.unsplash.com/photo-1522364723953-452d3431c267',
' https://images.unsplash.com/photo-1513938709626-033611b8cc03',
' https://images.unsplash.com/photo-1507143550189-fed454f93097',
' https://images.unsplash.com/photo-1493976040374-85c8e12f0c0e',
' https://images.unsplash.com/photo-1504198453319-5ce911bafcde',
' https://images.unsplash.com/photo-1530122037265-a5f1f91d3b99',
' https://images.unsplash.com/photo-1516972810927-80185027ca84',
' https://images.unsplash.com/photo-1550439062-609e1531270e',
]start_time = time.perf_counter()
defnedlastingsbilde(img_url):
img_bytes = requests.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
med åpen (img_name, 'wb') som img_file:
img_file.write (img_bytes)
skrive ut(f'{img_name} ble lastet ned...')med concurrent.futures. ThreadPoolExecutor() som eksekutor:
executor.map (download_image, img_urls)finish_time = time.perf_counter()
skrive ut(f'Ferdig i {finish_time-start_time} sekunder')
Etter å ha introdusert tråding. Tiden reduseres betydelig. Det tok bare 4 sekunder å fullføre gjennomføringen av programmet.
Scenarier egnet for tråding
Noen av scenariene som er egnet for tråding er:
- I/O-bundne oppgaver: Hvis programmet bruker mesteparten av tiden på å vente på at inn- eller utdataoperasjoner skal fullføres. Threading kan forbedre ytelsen ved å la andre oppgaver utføres mens man venter på at I/O-operasjoner skal fullføres.
- Nettskraping: Nettskraping innebærer å lage HTTP-forespørsler og analysere HTML-svar. Threading hjelper til med å fremskynde prosessen ved å tillate deg å gjøre flere forespørsler samtidig.
- CPU-bundne oppgaver: Threading kan bidra til å forbedre ytelsen ved å la flere oppgaver utføres parallelt.
Gjør deg kjent med tråding på andre språk
Python er ikke det eneste språket som støtter tråding. De fleste programmeringsspråk støtter en eller annen form for tråding. Det er viktig å sette seg inn i implementeringen av tråder på andre språk. Dette utstyrer deg med de nødvendige ferdighetene for å takle ulike scenarier der tråding kan gjelde.