Threading reducerer udførelsestiden for et program betydeligt. Lær, hvordan du implementerer threading i Python.

Eksekveringstid er et af de almindelige mål for effektiviteten af ​​et program. Jo hurtigere udførelsestiden er, jo bedre er programmet. Threading er en teknik, der gør det muligt for et program at udføre flere opgaver eller processer samtidigt.

Du lærer, hvordan du bruger den indbyggede Python trådning modul og samtidige.funktioner modul. Begge disse moduler tilbyder enkle måder at oprette og administrere tråde på

Betydningen af ​​trådning

Trådning reducerer den tid, et program tager at fuldføre et job. Hvis jobbet indeholder flere uafhængige opgaver, kan du bruge threading til at køre opgaverne samtidigt, hvilket reducerer programmets ventetid på, at en opgave er færdig, før du går videre til den næste.

For eksempel et program, der downloader flere billedfiler fra internettet. Dette program kan bruge threading til at downloade filerne parallelt i stedet for én ad gangen. Dette eliminerer den tid, programmet skal vente på, at downloadprocessen af ​​en fil er fuldført, før den går videre til den næste.

instagram viewer

Indledende program før trådning

Funktionen i det følgende program repræsenterer en opgave. Opgaven er at pause udførelsen af ​​programmet i et sekund. Programmet kalder funktionen to gange og skaber derfor to opgaver. Den beregner derefter den tid, det tog for hele programmet at køre, og viser det derefter på skærmen.

importere tid

start_time = time.perf_counter()

defpause():
Print('Sover 1 sekund...')
tid.søvn(1)
Print('Færdig med at sove...')

pause()
pause()
finish_time = time.perf_counter()
Print(f' Færdig i {runde (sluttid - starttid, 2)} sekund(er)')

Outputtet viser, at programmet tog 2,01 sekunder at udføre. Hver opgave tog et sekund, og resten af ​​koden tog 0,01 sekunder at udføre.

Du kan bruge trådning til at udføre begge opgaver samtidigt. Dette vil tage begge opgaver et sekund at udføre.

Implementering af gevindskæring ved hjælp af gevindskæringsmodulet

For at ændre den oprindelige kode for at implementere trådning skal du importere trådning modul. Opret to tråde, tråd_1 og tråd_2 bruger Tråd klasse. Ring til Start metode på hver tråd for at starte dens eksekvering. Ring til tilslutte metode på hver tråd for at vente på, at deres eksekvering er fuldført, før resten af ​​programmet køres.

importere tid
importere trådning
start_time = time.perf_counter()

defpause():
Print('Sover 1 sekund...')
tid.søvn(1)
Print('Færdig med at sove...')

tråd_1 = trådning. Tråd (mål=pause)
tråd_2 = trådning. Tråd (mål=pause)

tråd_1.start()
tråd_2.start()

thread_1.join()
thread_2.join()

finish_time = time.perf_counter()
Print(f' Færdig i {runde (sluttid - starttid, 2)} sekund(er)')

Programmet kører begge tråde samtidigt. Dette vil reducere den tid, det tager at udføre begge opgaver.

Outputtet viser, at tiden det tager at køre de samme opgaver er omkring et sekund. Dette er halvdelen af ​​den tid, det oprindelige program tog.

Implementering af trådning ved hjælp af concurrent.futures-modulet

Python 3.2 så introduktionen af concurrent.futures modul. Dette modul giver en grænseflade på højt niveau til udførelse af asynkrone opgaver ved hjælp af tråde. Det giver en enklere måde at udføre opgaver parallelt på.

For at ændre det oprindelige program til at bruge tråding skal du importere modulet Concurrent.features. Brug ThreadPoolExecutor klasse fra concurrent.futures-modulet for at skabe en pulje af tråde. Indsend pause funktion til poolen to gange. Det Indsend metode returnerer en fremtid objekt, der repræsenterer resultatet af funktionskaldet.

Gentag over futures og udskrive deres resultater ved hjælp af resultat metode.

importere tid
importere concurrent.futures

start_time = time.perf_counter()

defpause():
Print('Sover 1 sekund...')
tid.søvn(1)
Vend tilbage'Færdig med at sove...'

med concurrent.futures. ThreadPoolExecutor() som bobestyrer:
resultater = [executor.submit (pause) til _ i rækkevidde(2)]
til f i concurrent.futures.as_completed (resultater):
print (f.result())

finish_time = time.perf_counter()

Print(f' Færdig i {runde (sluttid - starttid, 2)} sekund(er)')

Concurrent.features-modulet sørger for at starte og forbinde trådene for dig. Dette gør din kode renere.

Outputtet er identisk med gevindmodulets. Gevindmodulet er nyttigt til simple tilfælde, hvor du skal køre et par tråde parallelt. På den anden side er concurrent.futures-modulet nyttigt til mere komplekse sager, hvor du skal køre mange opgaver samtidigt.

Brug af trådning i et virkeligt scenarie

Brug af tråde til at køre ovenstående program reducerede tiden med et sekund. I den virkelige verden sparer tråde mere tid. Opret et program, der downloader billeder fra internettet. Start med skabe et nyt virtuelt miljø. Kør følgende kommando i terminalen for at installere anmodninger bibliotek:

pip installationsanmodninger

Anmodningsbiblioteket giver dig mulighed for at sende HTTP-anmodninger. Importer anmodningsbiblioteket og tidsbiblioteket.

importere anmodninger
importere tid

Opret en liste over URL'er for de billeder, du gerne vil downloade. Lad dem være mindst ti, så du kan mærke en væsentlig forskel, når du implementerer gevindskæring.

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øjfe hen over listen af URL'er, der downloader hvert billede til den samme mappe, som indeholder dit projekt. Vis den tid, det tager at downloade billederne ved at trække sluttidspunktet fra starttidspunktet.

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 åben (img_name, 'wb') som img_file:
img_file.write (img_bytes)
Print(f'{img_name} blev downloadet...')
finish_time = time.perf_counter()
Print(f' Færdig i {finish_time - start_time} sekunder')

Programmet tager omkring 22 sekunder at downloade de 12 billeder. Det kan variere for dig, da den tid det tager at downloade billederne også afhænger af hastigheden på dit internet.

Rediger programmet til at bruge threading ved hjælp af concurrent.features-modulet. Brug en funktion i stedet for en loop. Dette er den funktion, du vil videregive til bobestyrer eksempel.

importere anmodninger
importere tid
importere concurrent.futures

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',
]

start_time = time.perf_counter()

defdownload_billede(img_url):
img_bytes = requests.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
med åben (img_name, 'wb') som img_file:
img_file.write (img_bytes)
Print(f'{img_name} blev downloadet...')

med concurrent.futures. ThreadPoolExecutor() som bobestyrer:
executor.map (download_image, img_urls)

finish_time = time.perf_counter()

Print(f' Færdig i {finish_time-start_time} sekunder')

Efter at have introduceret trådning. Tiden reduceres betydeligt. Det tog kun 4 sekunder at fuldføre udførelsen af ​​programmet.

Scenarier egnet til trådning

Nogle af de scenarier, der er egnede til trådning er:

  • I/O bundne opgaver: Hvis programmet bruger størstedelen af ​​tiden på at vente på, at input- eller outputhandlinger er afsluttet. Threading kan forbedre ydeevnen ved at tillade, at andre opgaver udføres, mens man venter på, at I/O-operationer er fuldført.
  • Web skrabning: Webscraping involverer at lave HTTP-anmodninger og parse HTML-svar. Threading hjælper med at fremskynde processen ved at give dig mulighed for at lave flere anmodninger samtidigt.
  • CPU-bundne opgaver: Threading kan hjælpe med at forbedre ydeevnen ved at tillade flere opgaver at udføre parallelt.

Bliv fortrolig med trådning på andre sprog

Python er ikke det eneste sprog, der understøtter threading. De fleste programmeringssprog understøtter en form for trådning. Det er vigtigt at sætte sig ind i implementeringen af ​​tråde på andre sprog. Dette udstyrer dig med de nødvendige færdigheder til at tackle forskellige scenarier, hvor threading kan finde anvendelse.