Nitno povezovanje bistveno skrajša čas izvajanja programa. Naučite se implementirati niti v Pythonu.

Čas izvajanja je eno od pogostih meril učinkovitosti programa. Čim hitrejši je čas izvajanja, tem boljši je program. Threading je tehnika, ki omogoča programu, da izvaja več nalog ali procesov hkrati.

Naučili se boste uporabljati vgrajeni Python vrezovanje navojev modul in sočasne.značilnosti modul. Oba modula ponujata preproste načine za ustvarjanje in upravljanje niti

Pomen navojev

Nitno povezovanje skrajša čas, ki ga program potrebuje za dokončanje opravila. Če opravilo vsebuje več neodvisnih opravil, lahko uporabite navoje za sočasno izvajanje opravil, kar skrajša čakalni čas programa, da se eno opravilo zaključi, preden se premaknete na naslednje.

Na primer, program, ki prenese več slikovnih datotek iz interneta. Ta program lahko uporablja navoje za prenos datotek vzporedno in ne eno za drugo. To odpravi čas, ki bi ga moral program čakati, da se zaključi postopek prenosa ene datoteke, preden se premakne na naslednjo.

instagram viewer

Začetni program pred navojem

Funkcija v naslednjem programu predstavlja nalogo. Naloga je, da za eno sekundo zaustavimo izvajanje programa. Program dvakrat pokliče funkcijo in tako ustvari dve nalogi. Nato izračuna čas, potreben za izvajanje celotnega programa, in ga nato prikaže na zaslonu.

uvoz čas

start_time = time.perf_counter()

defpavza():
natisni("Spim 1 sekundo ...")
time.sleep(1)
natisni(»Končal s spanjem ...«)

pavza()
pavza()
finish_time = time.perf_counter()
natisni(f'Končano v {krog (končni_čas - začetni_čas, 2)} sekunda (e)')

Rezultat kaže, da je izvajanje programa trajalo 2,01 sekunde. Vsaka naloga je trajala eno sekundo, preostala koda pa je za izvedbo potrebovala 0,01 sekunde.

Niti lahko uporabite za sočasno izvajanje obeh nalog. Izvedba obeh nalog bo trajala eno sekundo.

Implementacija Threading z uporabo modula Threading Module

Če želite spremeniti začetno kodo za izvajanje navojev, uvozite vrezovanje navojev modul. Ustvarite dve niti, nit_1 in nit_2 uporabljati nit razred. Pokličite začetek metodo za vsako nit za začetek njenega izvajanja. Pokličite pridruži se na vsaki niti, da počaka, da se njihova izvedba zaključi, preden se izvede preostali del programa.

uvoz čas
uvoz vrezovanje navojev
start_time = time.perf_counter()

defpavza():
natisni("Spim 1 sekundo ...")
time.sleep(1)
natisni(»Končal s spanjem ...«)

nit_1 = navoj. Nit (cilj=pavza)
navoj_2 = navoj. Nit (cilj=pavza)

thread_1.start()
thread_2.start()

thread_1.join()
thread_2.join()

finish_time = time.perf_counter()
natisni(f'Končano v {krog (končni_čas - začetni_čas, 2)} sekunda (e)')

Program bo izvajal obe niti hkrati. To bo zmanjšalo čas, potreben za izpolnitev obeh nalog.

Rezultat kaže, da je čas, potreben za izvajanje istih nalog, približno sekunda. To je polovica časa, ki ga je porabil začetni program.

Implementacija niti z uporabo modula concurrent.futures

Python 3.2 je videl uvedbo concurrent.futures modul. Ta modul nudi vmesnik na visoki ravni za izvajanje asinhronih nalog z uporabo niti. Omogoča enostavnejši način vzporednega izvajanja nalog.

Če želite spremeniti začetni program za uporabo niti, uvozite modul concurrent.features. Uporabi ThreadPoolExecutor razreda iz modula concurrent.futures, da ustvarite skupino niti. Predložite pavza v bazen dvakrat. The predložiti metoda vrne a prihodnost objekt, ki predstavlja rezultat klica funkcije.

Ponovi čez terminske pogodbe in natisnejo rezultate z uporabo rezultat metoda.

uvoz čas
uvoz concurrent.futures

start_time = time.perf_counter()

defpavza():
natisni("Spim 1 sekundo ...")
time.sleep(1)
vrnitev»Končal s spanjem ...«

z concurrent.futures. ThreadPoolExecutor() kot izvajalec:
rezultati = [executor.submit (pavza) za _ v obseg (2)]
za f v concurrent.futures.as_completed (rezultati):
natisni (f.result())

finish_time = time.perf_counter()

natisni(f'Končano v {krog (končni_čas - začetni_čas, 2)} sekunda (e)')

Modul concurrent.features namesto vas poskrbi za zagon in združevanje niti. Tako je vaša koda čistejša.

Izhod je enak izhodu modula za navoje. Modul za navoje je uporaben za preproste primere, ko morate vzporedno izvajati nekaj niti. Po drugi strani pa je modul concurrent.futures uporaben za bolj zapletene primere, ko morate sočasno izvajati veliko nalog.

Uporaba niti v scenariju resničnega sveta

Uporaba niti za izvajanje zgornjega programa je zmanjšala čas za eno sekundo. V resničnem svetu niti prihranijo več časa. Ustvarite program, ki prenaša slike iz interneta. Začni z ustvarjanje novega virtualnega okolja. Zaženite naslednji ukaz v terminalu, da namestite zahteve knjižnica:

zahteve za namestitev pip

Knjižnica zahtev vam bo omogočila pošiljanje zahtev HTTP. Uvozite knjižnico zahtev in časovno knjižnico.

uvoz zahteve
uvoz čas

Ustvarite seznam URL-jev slik, ki jih želite prenesti. Naj jih bo vsaj deset, da boste lahko opazili pomembno razliko pri izvajanju navojev.

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

Preglejte seznam URL-jev, ki prenašajo vsako sliko v isto mapo, v kateri je vaš projekt. Prikažite čas, potreben za prenos slik, tako da odštejete končni čas od začetnega časa.

start_time = time.perf_counter()
za img_url v img_urls:
img_bytes = requests.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
z odprto (img_ime, 'wb') kot img_file:
img_file.write (img_bytes)
natisni(f'{img_name} je bilo preneseno ...')
finish_time = time.perf_counter()
natisni(f'Končano v {finish_time - start_time} sekund')

Program potrebuje približno 22 sekund, da prenese 12 slik. Za vas se lahko razlikuje, saj je čas prenosa slik odvisen tudi od hitrosti vašega interneta.

Spremenite program za uporabo navojev z modulom concurrent.features. Namesto zanke uporabite funkcijo. To je funkcija, ki jo boste posredovali izvršitelj primerek.

uvoz zahteve
uvoz čas
uvoz 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_image(img_url):
img_bytes = requests.get (img_url).content
img_name = img_url.split('/')[3]
img_name = f'{img_name}.jpg'
z odprto (img_ime, 'wb') kot img_file:
img_file.write (img_bytes)
natisni(f'{img_name} je bilo preneseno ...')

z concurrent.futures. ThreadPoolExecutor() kot izvajalec:
izvajalec.map (prenos_slike, img_urls)

finish_time = time.perf_counter()

natisni(f'Končano v {finish_time-start_time} sekund')

Po uvedbi navojev. Čas se bistveno zmanjša. Izvedba programa je trajala le 4 sekunde.

Scenariji, primerni za Threading

Nekateri scenariji, primerni za navoje, so:

  • V/I vezana opravila: če program porabi večino časa za čakanje na dokončanje vhodnih ali izhodnih operacij. Niti lahko izboljšajo zmogljivost tako, da omogočijo izvajanje drugih nalog med čakanjem na zaključek V/I operacij.
  • Spletno strganje: Spletno strganje vključuje izdelavo zahtev HTTP in razčlenjevanje odgovorov HTML. Threading pomaga pospešiti postopek, saj vam omogoča, da naredite več zahtev hkrati.
  • Opravila, vezana na procesor: Nitno povezovanje lahko pomaga izboljšati zmogljivost tako, da omogoča vzporedno izvajanje več nalog.

Seznanite se z navojem v drugih jezikih

Python ni edini jezik, ki podpira navoje. Večina programskih jezikov podpira neko obliko niti. Pomembno je, da se seznanite z izvajanjem niti v drugih jezikih. To vas opremi s potrebnimi veščinami za reševanje različnih scenarijev, kjer lahko pride do uporabe niti.