logo

Večnitnost v Pythonu

Ta članek obravnava osnove večnitnosti v programskem jeziku Python. Tako kot večprocesiranje , je večnitnost način za doseganje večopravilnosti. Pri večnitnosti je koncept niti se uporablja. Najprej razumemo koncept nit v računalniški arhitekturi.

Kaj je proces v Pythonu?

V računalništvu, a postopek je primerek računalniškega programa, ki se izvaja. Vsak proces ima 3 osnovne komponente:

  • Izvedljiv program.
  • Povezani podatki, ki jih potrebuje program (spremenljivke, delovni prostor, medpomnilniki itd.)
  • Kontekst izvajanja programa (stanje procesa)

Uvod v Python Threading

A nit je entiteta znotraj procesa, ki jo je mogoče načrtovati za izvedbo. Poleg tega je najmanjša enota obdelave, ki jo je mogoče izvesti v OS (operacijskem sistemu). Preprosto povedano, nit je zaporedje takšnih ukazov znotraj programa, ki se lahko izvajajo neodvisno od druge kode. Zaradi poenostavitve lahko domnevate, da je nit preprosto podmnožica procesa! Nit vsebuje vse te informacije v a Blok za nadzor niti (TCB) :



  • Identifikator niti: Enolični ID (TID) je dodeljen vsaki novi niti
  • Kazalec sklada: Kaže na sklad niti v procesu. Sklad vsebuje lokalne spremenljivke v obsegu niti.
  • Programski števec: register, ki hrani naslov ukaza, ki ga trenutno izvaja nit.
  • Stanje niti: lahko teče, pripravljen, čaka, začne ali konča.
  • Nabor registra niti: registri, dodeljeni niti za izračune.
  • Kazalec nadrejenega procesa: Kazalec na blok za nadzor procesa (PCB) procesa, v katerem živi nit.

Razmislite o spodnjem diagramu, da boste razumeli razmerje med procesom in njegovo nitjo:

večnitnost-python-11

Razmerje med procesom in njegovo nitjo

V enem procesu lahko obstaja več niti, kjer:

  • Vsaka nit vsebuje svojega register set in lokalne spremenljivke (shranjene v skladu) .
  • Vse niti procesa so v skupni rabi globalne spremenljivke (shranjene v kopici) in programsko kodo .

Oglejte si spodnji diagram, da razumete, kako v pomnilniku obstaja več niti:

večnitnost-python-21

Obstoj več niti v pomnilniku

Uvod v niti v Pythonu

Večnitnost je definiran kot sposobnost procesorja, da hkrati izvaja več niti. V preprostem enojedrnem procesorju je to doseženo s pogostim preklapljanjem med nitmi. To se imenuje preklapljanje konteksta . Pri preklopu konteksta se stanje niti shrani, stanje druge niti pa se naloži vsakič, ko pride do kakršne koli prekinitve (zaradi V/I ali ročno nastavljene). Preklapljanje konteksta poteka tako pogosto, da se zdi, da vse niti tečejo vzporedno (to se imenuje večopravilnost ).

Oglejte si spodnji diagram, v katerem proces vsebuje dve aktivni niti:

večnitnost-python-31

Večnitnost

Večnitnost v Pythonu

noter Python , the vrezovanje navojev modul ponuja zelo preprost in intuitiven API za ustvarjanje več niti v programu. Poskusimo razumeti kodo večnitnosti korak za korakom.

Korak 1: Uvozni modul

Najprej uvozite modul za navoje.

import threading>

2. korak: Ustvarite nit

tiskanje iz jave

Če želite ustvariti novo nit, ustvarimo predmet nit razred. Kot parametra vzame 'target' in 'args'. The tarča je funkcija, ki jo izvede nit, medtem ko je args je argumenti, ki bodo posredovani ciljni funkciji.

t1 = threading.Thread(target, args) t2 = threading.Thread(target, args)>

3. korak: Začni nit

Za začetek niti uporabimo začetek() metoda razreda Thread.

t1.start() t2.start()>

4. korak: Končaj nit Izvedba

Ko se niti začnejo, se trenutni program (lahko si ga predstavljate kot glavno nit) prav tako nadaljuje z izvajanjem. Za zaustavitev izvajanja trenutnega programa, dokler nit ni dokončana, uporabimo pridruži se() metoda.

t1.join() t2.join()>

Posledično bo trenutni program najprej počakal na dokončanje t1 in potem t2 . Ko so končani, se izvedejo preostali stavki trenutnega programa.

primer:

Oglejmo si preprost primer uporabe modula za navoje.

Ta koda prikazuje, kako uporabiti Pythonov modul za navoje za sočasni izračun kvadrata in kuba števila. Dve niti, t1> in t2> , so ustvarjeni za izvajanje teh izračunov. Zaženejo se in njihovi rezultati se natisnejo vzporedno, preden program natisne Done! ko sta obe niti končani. Nitnost se uporablja za doseganje vzporednosti in izboljšanje zmogljivosti programa, ko se ukvarjamo z računsko intenzivnimi nalogami.

Python3

regex v Javi




import> threading> def> print_cube(num):> >print>(>'Cube: {}'> .>format>(num>*> num>*> num))> def> print_square(num):> >print>(>'Square: {}'> .>format>(num>*> num))> if> __name__>=>=>'__main__'>:> >t1>=> threading.Thread(target>=>print_square, args>=>(>10>,))> >t2>=> threading.Thread(target>=>print_cube, args>=>(>10>,))> >t1.start()> >t2.start()> >t1.join()> >t2.join()> >print>(>'Done!'>)>

>

>

Izhod:

Square: 100 Cube: 1000 Done!>

Za boljše razumevanje delovanja zgornjega programa si oglejte spodnji diagram:

večnitnost-python-4

Večnitnost

primer:

V tem primeru uporabljamo os.getpid() funkcijo za pridobitev ID-ja trenutnega procesa. Uporabljamo threading.main_thread() funkcijo za pridobitev predmeta glavne niti. V normalnih pogojih je glavna nit nit, iz katere je bil zagnan tolmač Python. ime atribut predmeta niti se uporablja za pridobitev imena niti. Nato uporabimo threading.current_thread() funkcijo za pridobitev trenutnega predmeta niti.

Razmislite o spodnjem programu Python, v katerem natisnemo ime niti in ustrezen proces za vsako nalogo.

Ta koda prikazuje, kako uporabiti Pythonov modul za navoje za sočasno izvajanje dveh nalog. Glavni program sproži dve niti, t1> in t2> , od katerih je vsak odgovoren za izvedbo določene naloge. Niti tečejo vzporedno, koda pa zagotavlja informacije o ID-ju procesa in imenih niti. Theos>modul se uporablja za dostop do ID-ja procesa in ' threading'> modul se uporablja za upravljanje niti in njihovo izvajanje.

Python3




import> threading> import> os> def> task1():> >print>(>'Task 1 assigned to thread: {}'>.>format>(threading.current_thread().name))> >print>(>'ID of process running task 1: {}'>.>format>(os.getpid()))> def> task2():> >print>(>'Task 2 assigned to thread: {}'>.>format>(threading.current_thread().name))> >print>(>'ID of process running task 2: {}'>.>format>(os.getpid()))> if> __name__>=>=> '__main__'>:> >print>(>'ID of process running main program: {}'>.>format>(os.getpid()))> >print>(>'Main thread name: {}'>.>format>(threading.current_thread().name))> >t1>=> threading.Thread(target>=>task1, name>=>'t1'>)> >t2>=> threading.Thread(target>=>task2, name>=>'t2'>)> >t1.start()> >t2.start()> >t1.join()> >t2.join()>

preimenovanje imenika linux

>

>

Izhod:

ID of process running main program: 1141 Main thread name: MainThread Task 1 assigned to thread: t1 ID of process running task 1: 1141 Task 2 assigned to thread: t2 ID of process running task 2: 1141>

Spodnji diagram pojasnjuje zgornji koncept:

večnitnost-python-5

Večnitnost

Torej, to je bil kratek uvod v večnitnost v Pythonu. Naslednji članek v tej seriji obravnava sinhronizacija med več niti . Večnitnost v Pythonu | 2. sklop (sinhronizacija)

Python ThreadPool

Bazen niti je zbirka niti, ki so ustvarjene vnaprej in jih je mogoče znova uporabiti za izvajanje več nalog. Modul concurrent.futures v Pythonu nudi razred ThreadPoolExecutor, ki olajša ustvarjanje in upravljanje skupine niti.

V tem primeru definiramo funkcijskega delavca, ki se bo izvajal v niti. Ustvarimo ThreadPoolExecutor z največ 2 delovnima nitima. Nato pošljemo dve nalogi v skupino z uporabo metode pošiljanja. Bazen upravlja izvajanje nalog v svojih delovnih nitih. Metodo zaustavitve uporabljamo za čakanje na dokončanje vseh nalog, preden se glavna nit nadaljuje.

Večnitnost vam lahko pomaga narediti vaše programe učinkovitejše in odzivnejše. Vendar je pomembno, da ste pri delu z nitmi previdni, da se izognete težavam, kot so pogoji tekmovanja in zastoji.

Ta koda uporablja skupino niti, ustvarjeno z concurrent.futures.ThreadPoolExecutor> za hkratno izvajanje dveh delovnih nalog. Glavna nit čaka, da delovne niti končajo z uporabo pool.shutdown(wait=True)> . To omogoča učinkovito vzporedno obdelavo nalog v večnitnem okolju.

Python3




import> concurrent.futures> def> worker():> >print>(>'Worker thread running'>)> pool>=> concurrent.futures.ThreadPoolExecutor(max_workers>=>2>)> pool.submit(worker)> pool.submit(worker)> pool.shutdown(wait>=>True>)> print>(>'Main thread continuing to run'>)>

>

abstraktne metode
>

Izhod

Worker thread running Worker thread running Main thread continuing to run>