Trådning minskar avsevärt exekveringstiden för ett program. Lär dig hur du implementerar trådning i Python.
Exekveringstid är ett av de vanligaste måtten på effektiviteten av ett program. Ju snabbare exekveringstiden är desto bättre är programmet. Trådning är en teknik som gör att ett program kan utföra flera uppgifter eller processer samtidigt.
Du kommer att lära dig hur du använder den inbyggda Python gängning modulen och samtidiga.funktioner modul. Båda dessa moduler erbjuder enkla sätt att skapa och hantera trådar
Betydelsen av att tråda
Trådning minskar den tid ett program tar att slutföra ett jobb. Om jobbet innehåller flera oberoende uppgifter kan du använda trådning för att köra uppgifterna samtidigt, vilket minskar programmets väntetid för en uppgift att slutföra innan du går vidare till nästa.
Till exempel ett program som laddar ner flera bildfiler från internet. Det här programmet kan använda trådning för att ladda ner filerna parallellt snarare än en åt gången. Detta eliminerar tiden som programmet skulle behöva vänta på att nedladdningsprocessen för en fil ska slutföras innan den går vidare till nästa.
Inledande program före trådning
Funktionen i följande program representerar en uppgift. Uppgiften är att pausa körningen av programmet i en sekund. Programmet anropar funktionen två gånger och skapar därför två uppgifter. Den beräknar sedan tiden det tog för hela programmet att köras och visar det sedan på skärmen.
importera tid
start_time = time.perf_counter()
defpaus():
skriva ut("Sover 1 sekund...")
tid.sömn(1)
skriva ut("Som färdigt...")
paus()
paus()
finish_time = time.perf_counter()
skriva ut(f' Avslutade i {runda (sluttid - starttid, 2)} sekund (s)')
Utdata visar att programmet tog 2,01 sekunder att köra. Varje uppgift tog en sekund och resten av koden tog 0,01 sekunder att utföra.
Du kan använda trådning för att utföra båda uppgifterna samtidigt. Detta kommer att ta båda uppgifterna en sekund att utföra.
Implementera gängning med hjälp av gängningsmodulen
För att ändra den ursprungliga koden för att implementera trådning, importera gängning modul. Skapa två trådar, tråd_1 och tråd_2 använda Tråd klass. Ring Start metod på varje tråd för att starta dess exekvering. Ring Ansluta sig metod på varje tråd för att vänta på att deras körning ska slutföras innan resten av programmet körs.
importera tid
importera gängning
start_time = time.perf_counter()defpaus():
skriva ut("Sover 1 sekund...")
tid.sömn(1)
skriva ut("Som färdigt...")tråd_1 = trådning. Tråd (mål=paus)
tråd_2 = trådning. Tråd (mål=paus)thread_1.start()
thread_2.start()thread_1.join()
thread_2.join()
finish_time = time.perf_counter()
skriva ut(f' Avslutade i {runda (sluttid - starttid, 2)} sekund (s)')
Programmet kommer att köra båda trådarna samtidigt. Detta kommer att minska den tid det tar att utföra båda uppgifterna.
Utdata visar att tiden det tar att köra samma uppgifter är cirka en sekund. Detta är hälften av tiden det inledande programmet tog.
Implementera trådning med hjälp av modulen concurrent.futures
Python 3.2 såg introduktionen av concurrent.futures modul. Denna modul tillhandahåller ett gränssnitt på hög nivå för exekvering av asynkrona uppgifter med hjälp av trådar. Det ger ett enklare sätt att utföra uppgifter parallellt.
För att ändra det ursprungliga programmet för att använda trådning, importera modulen concurrent.features. Använd ThreadPoolExecutor klass från modulen concurrent.futures för att skapa en pool av trådar. Skicka in paus fungera till poolen två gånger. De Skicka in metod returnerar en framtida objekt som representerar resultatet av funktionsanropet.
Iterera över terminer och skriva ut sina resultat med hjälp av resultat metod.
importera tid
importera concurrent.futuresstart_time = time.perf_counter()
defpaus():
skriva ut("Sover 1 sekund...")
tid.sömn(1)
lämna tillbaka"Som färdigt..."med concurrent.futures. ThreadPoolExecutor() som testamentsexekutor:
resultat = [executor.submit (paus) för _ i räckvidd(2)]
för f i concurrent.futures.as_completed (resultat):
print (f.result())finish_time = time.perf_counter()
skriva ut(f' Avslutade i {runda (sluttid - starttid, 2)} sekund (s)')
Modulen Concurrent.features tar hand om att starta och ansluta trådarna åt dig. Detta gör din kod renare.
Utgången är identisk med den för gängmodulen. Träningsmodulen är användbar för enkla fall där du behöver köra några trådar parallellt. Å andra sidan är modulen concurrent.futures användbar för mer komplexa fall där du behöver köra många uppgifter samtidigt.
Använda trådning i ett verkligt scenario
Genom att använda trådar för att köra programmet ovan minskade tiden med en sekund. I den verkliga världen sparar trådar mer tid. Skapa ett program som laddar ner bilder från internet. Börja med skapa en ny virtuell miljö. Kör följande kommando i terminalen för att installera förfrågningar bibliotek:
pip-installationsförfrågningar
Förfrågningsbiblioteket låter dig skicka HTTP-förfrågningar. Importera förfrågningsbiblioteket och tidsbiblioteket.
importera förfrågningar
importera tid
Skapa en lista med webbadresser till de bilder du vill ladda ner. Låt dem vara minst tio så att du kan märka en betydande skillnad när du implementerar gängning.
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',
]
Gå över listan av webbadresser som laddar ner varje bild till samma mapp som innehåller ditt projekt. Visa tiden det tar att ladda ner bilderna genom att subtrahera sluttiden från starttiden.
start_time = time.perf_counter()
för 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 öppna (img_name, 'wb') som img_file:
img_file.write (img_bytes)
skriva ut(f'{img_name} laddades ner...')
finish_time = time.perf_counter()
skriva ut(f' Avslutade i {finish_time - start_time} sekunder')
Programmet tar cirka 22 sekunder att ladda ner de 12 bilderna. Det kan variera för dig eftersom tiden det tar att ladda ner bilderna också beror på hastigheten på ditt internet.
Ändra programmet för att använda trådning med modulen concurrent.features. Använd en funktion istället för en loop. Det här är funktionen du kommer att skicka till testamentsexekutor exempel.
importera förfrågningar
importera tid
importera 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()
defdownload_image(img_url):
img_bytes = requests.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
med öppna (img_name, 'wb') som img_file:
img_file.write (img_bytes)
skriva ut(f'{img_name} laddades ner...')med concurrent.futures. ThreadPoolExecutor() som testamentsexekutor:
executor.map (download_image, img_urls)finish_time = time.perf_counter()
skriva ut(f' Avslutade i {finish_time-start_time} sekunder')
Efter att ha introducerat trådning. Tiden minskar avsevärt. Det tog bara 4 sekunder att slutföra exekveringen av programmet.
Scenarier som lämpar sig för trådning
Några av scenarierna som är lämpliga för trådning är:
- I/O-bundna uppgifter: Om programmet tillbringar större delen av tiden med att vänta på att inmatnings- eller utmatningsoperationer ska slutföras. Trådning kan förbättra prestandan genom att tillåta andra uppgifter att utföras i väntan på att I/O-operationer ska slutföras.
- Webskrapning: Webbskrapning innebär att göra HTTP-förfrågningar och analysera HTML-svar. Threading hjälper till att påskynda processen genom att du kan göra flera förfrågningar samtidigt.
- CPU-bundna uppgifter: Trådning kan hjälpa till att förbättra prestandan genom att tillåta flera uppgifter att utföras parallellt.
Bekanta dig med trådning på andra språk
Python är inte det enda språket som stöder trådning. De flesta programmeringsspråk stöder någon form av trådning. Det är viktigt att bekanta sig med implementeringen av trådar på andra språk. Detta utrustar dig med nödvändiga färdigheter för att hantera olika scenarier där trådning kan gälla.