Šajā rakstā ir apskatīti Python programmēšanas valodas daudzpavedienu pamati. Tieši kā daudzapstrāde , vairāku pavedienu izmantošana ir veids, kā panākt vairākuzdevumu veikšanu. Daudzpavedienu veidošanā jēdziens pavedieni tiek izmantots. Vispirms sapratīsim jēdzienu pavediens datoru arhitektūrā.
Kas ir process Python?
Datortehnikas jomā a process ir datorprogrammas gadījums, kas tiek izpildīts. Jebkuram procesam ir 3 pamatkomponenti:
statiskā funkcija java
- Izpildāma programma.
- Programmai nepieciešamie saistītie dati (mainīgie, darbvieta, buferi utt.)
- Programmas izpildes konteksts (procesa stāvoklis)
Ievads Python Threading
A pavediens ir entītija procesā, kuru var ieplānot izpildei. Turklāt tā ir mazākā apstrādes vienība, ko var veikt OS (operētājsistēmā). Vienkāršiem vārdiem sakot, pavediens ir šādu instrukciju secība programmā, ko var izpildīt neatkarīgi no cita koda. Vienkāršības labad varat pieņemt, ka pavediens ir vienkārši procesa apakškopa! Pavediens satur visu šo informāciju sadaļā a Vītnes vadības bloks (TCB) :
- Pavediena identifikators: Katram jaunam pavedienam tiek piešķirts unikālais ID (TID).
- Stack rādītājs: Procesā norāda uz pavediena kopu. Kaudzīte satur lokālos mainīgos, kas atrodas pavediena darbības jomā.
- Programmu skaitītājs: reģistrs, kurā tiek glabāta instrukcijas adrese, kuru pašlaik izpilda pavediens.
- Pavediena stāvoklis: var darboties, gatavs, gaidīt, sākt vai pabeigts.
- Pavedienu reģistrs: reģistri, kas piešķirti pavedienam aprēķiniem.
- Vecāku procesa rādītājs: Rādītājs uz procesa vadības bloku (PCB), kurā darbojas pavediens.
Apsveriet tālāk redzamo diagrammu, lai izprastu attiecības starp procesu un tā pavedienu:

Attiecības starp procesu un tā pavedienu
Vienā procesā var pastāvēt vairāki pavedieni, kur:
- Katrs pavediens satur savu reģistra komplekts un vietējie mainīgie (saglabāti kaudzē) .
- Visi procesa pavedieni tiek koplietoti globālie mainīgie (glabājas kaudzē) un programmas kods .
Apsveriet tālāk redzamo diagrammu, lai saprastu, kā atmiņā pastāv vairāki pavedieni:

Vairāku pavedienu esamība atmiņā
Ievads pavedienu veidošanā Python
Daudzpavedienu veidošana tiek definēts kā procesora spēja izpildīt vairākus pavedienus vienlaikus. Vienkāršā, viena kodola CPU tas tiek panākts, izmantojot biežu pārslēgšanos starp pavedieniem. To sauc par konteksta maiņa . Konteksta pārslēgšanā pavediena stāvoklis tiek saglabāts un cita pavediena stāvoklis tiek ielādēts ikreiz, kad notiek pārtraukums (I/O dēļ vai manuāli iestatīts). Konteksta pārslēgšana notiek tik bieži, ka šķiet, ka visi pavedieni darbojas paralēli (to sauc par daudzuzdevumu veikšana ).
Apsveriet tālāk redzamo diagrammu, kurā process satur divus aktīvus pavedienus:

Daudzpavedienu veidošana
Daudzpavedienu veidošana Python
In Python , vītņošana modulis nodrošina ļoti vienkāršu un intuitīvu API vairāku pavedienu izveidošanai programmā. Mēģināsim soli pa solim izprast daudzpavedienu kodu.
1. darbība: Importēšanas modulis
Vispirms importējiet vītņu moduli.
import threading>
2. darbība: Izveidojiet pavedienu
Lai izveidotu jaunu pavedienu, mēs izveidojam objektu no Pavediens klasē. Kā parametri tiek izmantoti “mērķis” un “arguments”. The mērķis ir funkcija, kas jāizpilda pavedienam, savukārt args ir argumenti, kas jānodod mērķa funkcijai.
t1 = threading.Thread(target, args) t2 = threading.Thread(target, args)>
3. darbība: Sāciet pavedienu
Lai sāktu pavedienu, mēs izmantojam sākt() Thread klases metode.
t1.start() t2.start()>
4. darbība: Beigt pavedienu Izpilde
Kad pavedieni sākas, pašreizējā programma (varat to uzskatīt par galveno pavedienu) arī turpina izpildīt. Lai apturētu pašreizējās programmas izpildi, līdz pavediens ir pabeigts, mēs izmantojam pievienoties () metodi.
t1.join() t2.join()>
Tā rezultātā pašreizējā programma vispirms gaidīs, līdz tiks pabeigta t1 un tad t2 . Kad tie ir pabeigti, tiek izpildīti atlikušie pašreizējās programmas priekšraksti.
Piemērs:
Apskatīsim vienkāršu piemēru, izmantojot vītņu moduli.
Šis kods parāda, kā izmantot Python vītņu moduli, lai vienlaikus aprēķinātu skaitļa kvadrātu un kubu. Divi pavedieni, t1> un t2> , ir izveidoti, lai veiktu šos aprēķinus. Tie tiek palaisti, un to rezultāti tiek izdrukāti paralēli, pirms programma izdrukā Gatavs! kad abi pavedieni ir beigušies. Vītņošana tiek izmantota, lai panāktu paralēlismu un uzlabotu programmas veiktspēju, veicot skaitļošanas ietilpīgus uzdevumus.
Python3
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!'>)> |
datu tipi java
>
>
Izvade:
Square: 100 Cube: 1000 Done!>
Apsveriet tālāk redzamo diagrammu, lai labāk izprastu, kā darbojas iepriekš minētā programma.

Daudzpavedienu veidošana
Piemērs:
Šajā piemērā mēs izmantojam os.getpid() funkcija, lai iegūtu pašreizējā procesa ID. Mēs izmantojam threading.main_thread() funkcija, lai iegūtu galvenā pavediena objektu. Normālos apstākļos galvenais pavediens ir pavediens, no kura tika palaists Python tulks. nosaukums pavediena objekta atribūts tiek izmantots, lai iegūtu pavediena nosaukumu. Tad mēs izmantojam pavediens.current_thread() funkcija, lai iegūtu pašreizējo pavediena objektu.
Apsveriet tālāk sniegto Python programmu, kurā mēs izdrukājam pavediena nosaukumu un atbilstošo procesu katram uzdevumam.
Šis kods parāda, kā izmantot Python pavedienu moduli, lai vienlaikus izpildītu divus uzdevumus. Galvenā programma uzsāk divus pavedienus, t1> un t2> , katrs ir atbildīgs par konkrēta uzdevuma izpildi. Pavedieni darbojas paralēli, un kods sniedz informāciju par procesa ID un pavedienu nosaukumiem. Theos>modulis tiek izmantots, lai piekļūtu procesa ID, un ' threading'> modulis tiek izmantots, lai pārvaldītu pavedienus un to izpildi.
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()> |
>
>
Izvade:
git push komanda
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>
Tālāk sniegtā diagramma izskaidro iepriekš minēto jēdzienu:

Daudzpavedienu veidošana
Tātad, šis bija īss ievads vairāku pavedienu veidošanā Python. Nākamais šīs sērijas raksts aptver sinhronizācija starp vairākiem pavedieniem . Daudzpavedienu veidošana Python | 2. kopa (sinhronizācija)
Python ThreadPool
Pavedienu kopums ir pavedienu kolekcija, kas ir izveidota iepriekš un ko var atkārtoti izmantot vairāku uzdevumu izpildei. Concurrent.futures modulis programmā Python nodrošina ThreadPoolExecutor klasi, kas atvieglo pavedienu pūla izveidi un pārvaldību.
Šajā piemērā mēs definējam funkcijas darbinieku, kas darbosies pavedienā. Mēs izveidojam ThreadPoolExecutor ar ne vairāk kā 2 darbinieku pavedieniem. Pēc tam mēs iesniedzam divus uzdevumus pūlam, izmantojot iesniegšanas metodi. Pūls pārvalda uzdevumu izpildi savos darbinieku pavedienos. Mēs izmantojam izslēgšanas metodi, lai gaidītu visu uzdevumu pabeigšanu, pirms turpinās galvenais pavediens.
Daudzpavedienu izmantošana var palīdzēt padarīt programmas efektīvākas un atsaucīgākas. Tomēr ir svarīgi būt uzmanīgiem, strādājot ar pavedieniem, lai izvairītos no tādām problēmām kā sacensību apstākļi un strupceļi.
Šis kods izmanto pavedienu pūlu, kas izveidots ar concurrent.futures.ThreadPoolExecutor> lai vienlaikus izpildītu divus darbinieku uzdevumus. Galvenais pavediens gaida, līdz darbinieka pavedieni beigs lietot pool.shutdown(wait=True)> . Tas ļauj efektīvi paralēli apstrādāt uzdevumus daudzpavedienu vidē.
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'>)> |
>
instanceof java
>Izvade
Worker thread running Worker thread running Main thread continuing to run>