Threading značajno smanjuje vrijeme izvođenja programa. Naučite kako implementirati niti u Pythonu.
Vrijeme izvršenja jedna je od uobičajenih mjera učinkovitosti programa. Što je brže vrijeme izvršenja, to je program bolji. Threading je tehnika koja programu omogućuje izvođenje više zadataka ili procesa istovremeno.
Naučit ćete kako koristiti ugrađeni Python narezivanje navoja modul i istodobne.osobine modul. Oba ova modula nude jednostavne načine za stvaranje i upravljanje nitima
Važnost navoja
Threading smanjuje količinu vremena potrebnog programu da dovrši posao. Ako posao sadrži više neovisnih zadataka, možete koristiti niti za istovremeno pokretanje zadataka, smanjujući vrijeme čekanja programa da jedan zadatak završi prije nego što prijeđete na sljedeći.
Na primjer, program koji preuzima više slikovnih datoteka s interneta. Ovaj program može koristiti niti za preuzimanje datoteka paralelno, a ne jednu po jednu. Ovo eliminira vrijeme koje bi program morao čekati da završi proces preuzimanja jedne datoteke prije nego što prijeđe na sljedeću.
Početni program prije urezivanja niti
Funkcija u sljedećem programu predstavlja zadatak. Zadatak je pauzirati izvođenje programa na jednu sekundu. Program dvaput poziva funkciju i stvara dva zadatka. Zatim izračunava vrijeme potrebno da se cijeli program pokrene i zatim ga prikazuje na zaslonu.
uvoz vrijeme
start_time = time.perf_counter()
defpauza():
ispis("Spavam 1 sekundu...")
vrijeme.spavanje(1)
ispis('Gotovo spavanje...')
pauza()
pauza()
završno_vrijeme = vrijeme.perf_counter()
ispis(f'Završeno u {runda (vrijeme_završetka - vrijeme_početka, 2)} sekunda(e)')
Izlaz pokazuje da je izvršenje programa trajalo 2,01 sekundu. Za svaki je zadatak bila potrebna jedna sekunda, a izvršenje ostatka koda trajalo je 0,01 sekundu.
Možete koristiti niti za istodobno izvršavanje oba zadatka. Oba će zadatka trebati jednu sekundu za izvršenje.
Implementacija niti pomoću modula za izradu niti
Za izmjenu početnog koda za implementaciju niti, uvezite narezivanje navoja modul. Stvorite dvije niti, nit_1 i nit_2 koristiti Nit razreda. Nazovite početak metodu na svakoj niti za početak njenog izvođenja. Nazovite pridružiti metodu na svakoj niti da pričeka da se njihovo izvođenje završi prije nego što se izvrši ostatak programa.
uvoz vrijeme
uvoz narezivanje navoja
start_time = time.perf_counter()defpauza():
ispis("Spavam 1 sekundu...")
vrijeme.spavanje(1)
ispis('Gotovo spavanje...')thread_1 = navoj. Nit (cilj=pauza)
navoj_2 = navoj. Nit (cilj=pauza)thread_1.start()
thread_2.start()thread_1.join()
thread_2.join()
završno_vrijeme = vrijeme.perf_counter()
ispis(f'Završeno u {runda (vrijeme_završetka - vrijeme_početka, 2)} sekunda(e)')
Program će pokrenuti obje niti istovremeno. To će smanjiti količinu vremena potrebnog za postizanje oba zadatka.
Izlaz pokazuje da je vrijeme potrebno za izvođenje istih zadataka oko jedne sekunde. Ovo je upola manje vremena od početnog programa.
Implementacija niti pomoću modula concurrent.futures
Python 3.2 vidio je uvođenje istodobni.budućnosti modul. Ovaj modul pruža sučelje visoke razine za izvršavanje asinkronih zadataka pomoću niti. Omogućuje jednostavniji način paralelnog izvršavanja zadataka.
Da biste modificirali početni program za korištenje niti, uvezite modul concurrent.features. Koristiti ThreadPoolExecutor klase iz modula concurrent.futures za stvaranje skupa niti. Pošaljite pauza funkcija u bazen dva puta. The podnijeti metoda vraća a budućnost objekt koji predstavlja rezultat poziva funkcije.
Iterirajte preko budućnosti i ispisati svoje rezultate pomoću proizlaziti metoda.
uvoz vrijeme
uvoz istodobni.budućnostistart_time = time.perf_counter()
defpauza():
ispis("Spavam 1 sekundu...")
vrijeme.spavanje(1)
povratak'Gotovo spavanje...'s istovremeni.budućnosti. ThreadPoolExecutor() kao izvršitelj:
rezultati = [izvršitelj.submit (pauza) za _ u raspon (2)]
za f u concurrent.futures.as_completed (rezultati):
ispis (f.result())završno_vrijeme = vrijeme.perf_counter()
ispis(f'Završeno u {runda (vrijeme_završetka - vrijeme_početka, 2)} sekunda(e)')
Modul concurrent.features brine se za pokretanje i spajanje niti umjesto vas. Ovo čini vaš kod čišćim.
Izlaz je identičan onom modula za navoje. Modul Threading je koristan za jednostavne slučajeve kada morate pokrenuti nekoliko niti paralelno. S druge strane, modul concurrent.futures koristan je za složenije slučajeve gdje morate pokrenuti mnoge zadatke istovremeno.
Korištenje niti u scenariju stvarnog svijeta
Korištenje niti za pokretanje gornjeg programa smanjilo je vrijeme za jednu sekundu. U stvarnom svijetu niti štede više vremena. Napravite program koji preuzima slike s interneta. Počni od stvaranje novog virtualnog okruženja. Pokrenite sljedeću naredbu u terminalu da biste instalirali zahtjevi knjižnica:
pip instalacijski zahtjevi
Biblioteka zahtjeva omogućit će vam slanje HTTP zahtjeva. Uvezite biblioteku zahtjeva i biblioteku vremena.
uvoz zahtjevi
uvoz vrijeme
Napravite popis URL-ova slika koje želite preuzeti. Neka ih bude barem deset kako biste mogli primijetiti značajnu razliku kada implementirate threading.
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',
]
Prođite kroz popis URL-ova preuzimajući svaku sliku u istu mapu koja sadrži vaš projekt. Prikažite vrijeme potrebno za preuzimanje slika oduzimanjem vremena završetka od vremena početka.
start_time = time.perf_counter()
za img_url u img_urls:
img_bytes = requests.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
s otvori (img_ime, 'wb') kao img_file:
img_file.write (img_bytes)
ispis(f'{img_name} je preuzeto...')
završno_vrijeme = vrijeme.perf_counter()
ispis(f'Završeno u {vrijeme_završetka - vrijeme_početka} sekundi')
Programu su potrebne oko 22 sekunde za preuzimanje 12 slika. Može varirati za vas jer vrijeme potrebno za preuzimanje slika također ovisi o brzini vašeg interneta.
Izmijenite program za korištenje niti pomoću modula concurrent.features. Umjesto petlje, koristite funkciju. Ovo je funkcija koju ćete proslijediti izvršitelj primjer.
uvoz zahtjevi
uvoz vrijeme
uvoz istodobni.budućnostiimg_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()
defpreuzimanje_slike(img_url):
img_bytes = requests.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
s otvori (img_ime, 'wb') kao img_file:
img_file.write (img_bytes)
ispis(f'{img_name} je preuzeto...')s istovremeni.budućnosti. ThreadPoolExecutor() kao izvršitelj:
izvršitelj.mapa (slika_za_preuzimanje, img_urls)završno_vrijeme = vrijeme.perf_counter()
ispis(f'Završeno u {finish_time-start_time} sekundi')
Nakon uvođenja navoja. Vrijeme se značajno smanjuje. Za završetak izvršenja programa bile su potrebne samo 4 sekunde.
Scenariji prikladni za Threading
Neki od scenarija prikladnih za povezivanje su:
- I/O vezani zadaci: Ako program provodi većinu vremena čekajući da se dovrše ulazne ili izlazne operacije. Threading može poboljšati performanse dopuštajući drugim zadacima da se izvršavaju dok čekaju da se I/O operacije završe.
- Web struganje: Web scraping uključuje izradu HTTP zahtjeva i raščlanjivanje HTML odgovora. Threading pomaže ubrzati proces dopuštajući vam da napravite više zahtjeva istovremeno.
- CPU vezani zadaci: Threading može pomoći u poboljšanju performansi dopuštajući paralelno izvršavanje više zadataka.
Upoznajte se s nitima na drugim jezicima
Python nije jedini jezik koji podržava threading. Većina programskih jezika podržava neki oblik niti. Važno je upoznati se s implementacijom niti na drugim jezicima. To vas oprema potrebnim vještinama za rješavanje različitih scenarija u kojima se može primijeniti niti.