Threading výrazně snižuje dobu provádění programu. Naučte se implementovat vlákno v Pythonu.
Doba provádění je jedním z běžných měřítek účinnosti programu. Čím rychlejší je doba provádění, tím lepší je program. Threading je technika, která umožňuje programu provádět více úkolů nebo procesů současně.
Naučíte se používat vestavěný Python závitování modul a souběžné.vlastnosti modul. Oba tyto moduly nabízejí jednoduché způsoby vytváření a správy vláken
Význam závitování
Řezání vláken snižuje množství času, který program potřebuje k dokončení úlohy. Pokud úloha obsahuje více nezávislých úloh, můžete k souběžnému spouštění úloh použít vlákno, čímž se zkrátí doba čekání programu na dokončení jedné úlohy, než se přesune k další.
Například program, který stahuje více obrazových souborů z internetu. Tento program může využívat vláken ke stahování souborů paralelně, nikoli po jednom. To eliminuje dobu, po kterou by program musel čekat na dokončení procesu stahování jednoho souboru, než přejde k dalšímu.
Počáteční program před navlékáním
Funkce v následujícím programu představuje úkol. Úkolem je pozastavit provádění programu na jednu sekundu. Program volá funkci dvakrát, takže vytvoří dvě úlohy. Poté vypočítá dobu, za kterou se celý program spustil, a poté ji zobrazí na obrazovce.
import čas
start_time = time.perf_counter()
defpauza():
tisk('Spím 1 sekundu...')
čas.spánek(1)
tisk('Hotovo spát...')
pauza()
pauza()
finish_time = time.perf_counter()
tisk(f'Hotovo {round (finish_time - start_time, 2)} sekunda (s)')
Výstup ukazuje, že spuštění programu trvalo 2,01 sekundy. Každá úloha trvala jednu sekundu a provedení zbytku kódu trvalo 0,01 sekundy.
K souběžnému provádění obou úloh můžete použít vlákno. Provedení obou úkolů bude trvat jednu sekundu.
Implementace řezání závitů pomocí modulu řezání závitů
Chcete-li upravit počáteční kód pro implementaci vláken, importujte soubor závitování modul. Vytvořte dvě vlákna, vlákno_1 a vlákno_2 za použití Vlákno třída. Zavolej Start metoda na každém vlákně, aby se spustilo jeho provádění. Zavolej připojit metoda na každém vláknu, aby počkala na dokončení jejich provedení, než se spustí zbytek programu.
import čas
import závitování
start_time = time.perf_counter()defpauza():
tisk('Spím 1 sekundu...')
čas.spánek(1)
tisk('Hotovo spát...')thread_1 = závitování. Vlákno (cíl=pauza)
thread_2 = závitování. Vlákno (cíl=pauza)vlákno_1.start()
vlákno_2.start()thread_1.join()
thread_2.join()
finish_time = time.perf_counter()
tisk(f'Hotovo {round (finish_time - start_time, 2)} sekunda (s)')
Program poběží obě vlákna současně. Tím se zkrátí doba potřebná k provedení obou úkolů.
Výstup ukazuje, že čas potřebný ke spuštění stejných úloh je přibližně sekunda. To je polovina času, který trval původní program.
Implementace Threading pomocí modulu concurrent.futures
Python 3.2 viděl zavedení souběžné.budoucnosti modul. Tento modul poskytuje rozhraní na vysoké úrovni pro provádění asynchronních úloh pomocí vláken. Poskytuje jednodušší způsob provádění úloh paralelně.
Chcete-li upravit počáteční program tak, aby používal vlákna, importujte modul concurrent.features. Použijte ThreadPoolExecutor třídy z modulu concurrent.futures k vytvoření fondu vláken. Odešlete pauza do bazénu dvakrát. The Předložit metoda vrací a budoucnost objekt, který představuje výsledek volání funkce.
Iterujte přes futures a vytisknout jejich výsledky pomocí výsledek metoda.
import čas
import souběžné.budoucnostistart_time = time.perf_counter()
defpauza():
tisk('Spím 1 sekundu...')
čas.spánek(1)
vrátit se'Hotovo spát...'s souběžné.budoucnosti. ThreadPoolExecutor() tak jako vykonavatel:
výsledky = [executor.submit (pauza) pro _ v rozsah(2)]
pro F v concurrent.futures.as_completed (výsledky):
tisknout (f.result())finish_time = time.perf_counter()
tisk(f'Hotovo {round (finish_time - start_time, 2)} sekunda (s)')
Modul concurrent.features se postará o spouštění a připojování vláken za vás. Díky tomu bude váš kód čistší.
Výstup je shodný s výstupem závitového modulu. Modul vláken je užitečný pro jednoduché případy, kdy potřebujete paralelně spustit několik vláken. Na druhou stranu je modul concurrent.futures užitečný pro složitější případy, kdy potřebujete spouštět mnoho úloh současně.
Použití vláken ve scénáři reálného světa
Použití vláken ke spuštění výše uvedeného programu zkrátilo čas o jednu sekundu. V reálném světě vlákna šetří více času. Vytvořte program, který stáhne obrázky z internetu. Začněte tím vytvoření nového virtuálního prostředí. Spuštěním následujícího příkazu v terminálu nainstalujte žádosti knihovna:
požadavky na instalaci pip
Knihovna požadavků vám umožní odesílat požadavky HTTP. Importujte knihovnu požadavků a časovou knihovnu.
import žádosti
import čas
Vytvořte seznam adres URL obrázků, které chcete stáhnout. Nechte jich být alespoň deset, abyste si mohli všimnout výrazného rozdílu, když implementujete závitování.
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',
]
Projděte seznam URL, které stahují každý obrázek do stejné složky, která obsahuje váš projekt. Zobrazte čas potřebný ke stažení obrázků odečtením času ukončení od času zahájení.
start_time = time.perf_counter()
pro img_url v img_urls:
img_bytes = požadavky.get (img_url).obsah
img_name = img_url.split('/')[3]
img_name = F'{img_name}.jpg'
s otevřít (název_img, 'wb') tak jako img_file:
img_file.write (img_bytes)
tisk(F'{img_name} bylo staženo...')
finish_time = time.perf_counter()
tisk(f'Hotovo {finish_time - start_time} sekundy')
Stažení 12 obrázků trvá programu přibližně 22 sekund. Může se pro vás lišit, protože čas potřebný ke stažení obrázků závisí také na rychlosti vašeho internetu.
Upravte program tak, aby používal vlákna pomocí modulu concurrent.features. Místo smyčky použijte funkci. Toto je funkce, kterou předáte vykonavatel instance.
import žádosti
import čas
import souběžné.budoucnostiimg_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 = požadavky.get (img_url).obsah
img_name = img_url.split('/')[3]
img_name = F'{img_name}.jpg'
s otevřít (název_img, 'wb') tak jako img_file:
img_file.write (img_bytes)
tisk(F'{img_name} bylo staženo...')s souběžné.budoucnosti. ThreadPoolExecutor() tak jako vykonavatel:
executor.map (download_image, img_urls)finish_time = time.perf_counter()
tisk(f'Hotovo {finish_time-start_time} sekundy')
Po zavedení navlékání. Čas se výrazně zkracuje. Dokončení provádění programu trvalo pouze 4 sekundy.
Scénáře vhodné pro řezání závitů
Některé ze scénářů vhodných pro závitování jsou:
- Úlohy vázané na I/O: Pokud program stráví většinu času čekáním na dokončení vstupních nebo výstupních operací. Podprocesy mohou zlepšit výkon tím, že umožní provádění jiných úloh při čekání na dokončení I/O operací.
- Seškrabování webu: Web scraping zahrnuje vytváření požadavků HTTP a analýzu odpovědí HTML. Threading pomáhá urychlit proces tím, že umožňuje provádět více požadavků současně.
- Úlohy vázané na CPU: Threading může pomoci zlepšit výkon tím, že umožní paralelní provádění více úloh.
Seznamte se s vlákny v jiných jazycích
Python není jediný jazyk, který podporuje vytváření vláken. Většina programovacích jazyků podporuje nějakou formu vláken. Je důležité se seznámit s implementací vláken v jiných jazycích. To vás vybaví nezbytnými dovednostmi pro řešení různých scénářů, kde se může použít vlákno.