Šiame straipsnyje aprašomi kelių gijų kūrimo Python programavimo kalba pagrindai. Tiesiog kaip daugiafunkcinis apdorojimas , kelių gijų naudojimas yra būdas atlikti daugiafunkcinius veiksmus. Kelių gijų sąvoka siūlai yra naudojamas. Pirmiausia supraskime sąvoką siūlas kompiuterių architektūroje.
Kas yra Python procesas?
Skaičiuojant, a procesas yra vykdomos kompiuterio programos pavyzdys. Bet kurį procesą sudaro 3 pagrindiniai komponentai:
- Vykdomoji programa.
- Programai reikalingi susiję duomenys (kintamieji, darbo sritis, buferiai ir kt.)
- Programos vykdymo kontekstas (proceso būsena)
Įvadas į Python Threading
A siūlas yra proceso subjektas, kurį galima suplanuoti vykdyti. Be to, tai yra mažiausias apdorojimo vienetas, kurį galima atlikti OS (operacinėje sistemoje). Paprastais žodžiais tariant, gija yra tokių instrukcijų seka programoje, kurią galima vykdyti nepriklausomai nuo kito kodo. Paprastumo dėlei galite manyti, kad gija yra tiesiog proceso poaibis! Gijoje yra visa ši informacija a Siūlų valdymo blokas (TCB) :
- Gijos identifikatorius: Kiekvienai naujai gijai priskiriamas unikalus ID (TID).
- Stack rodyklė: Nurodo į gijos krūvą proceso metu. Kiemelyje yra vietiniai kintamieji pagal gijos sritį.
- Programų skaitiklis: registras, kuriame saugomas gija šiuo metu vykdomos instrukcijos adresas.
- Temos būsena: gali veikti, pasiruošti, laukti, pradėti arba baigti.
- Gijų registrų rinkinys: registrai, priskirti gijai skaičiavimams.
- Tėvų proceso žymeklis: Žymeklis į proceso valdymo bloką (PCB), kuriame veikia gija.
Apsvarstykite toliau pateiktą diagramą, kad suprastumėte ryšį tarp proceso ir jo gijos:

Proceso ir jo gijos santykis
Viename procese gali egzistuoti kelios gijos, kur:
- Kiekviena gija turi savo registro rinkinys ir vietiniai kintamieji (saugomi krūvoje) .
- Visos proceso gijos bendrinamos pasauliniai kintamieji (saugomi krūvoje) ir programos kodas .
Apsvarstykite toliau pateiktą diagramą, kad suprastumėte, kaip atmintyje yra kelios gijos:

Kelių gijų buvimas atmintyje
„Python“ gijų įvadas
Daugiagija apibrėžiamas kaip procesoriaus gebėjimas vienu metu vykdyti kelias gijas. Paprastame vieno branduolio procesoriuje tai pasiekiama dažnai perjungiant gijas. Tai vadinama konteksto perjungimas . Konteksto perjungimo metu gijos būsena išsaugoma ir kitos gijos būsena įkeliama kaskart, kai įvyksta bet koks pertraukimas (dėl įvesties / išvesties arba rankiniu būdu nustatytos). Konteksto perjungimas vyksta taip dažnai, kad atrodo, kad visos gijos veikia lygiagrečiai (tai vadinama daugiafunkcinis darbas ).
Apsvarstykite toliau pateiktą diagramą, kurioje procesą sudaro dvi aktyvios gijos:

Daugiagija
Kelių gijų kūrimas Python
Į Python , sriegimas modulis suteikia labai paprastą ir intuityvią API, skirtą programoje sukurti kelias gijas. Pabandykime žingsnis po žingsnio suprasti kelių gijų kodą.
1 žingsnis: Importavimo modulis
Pirmiausia importuokite sriegimo modulį.
import threading>
2 žingsnis: Sukurkite giją
Norėdami sukurti naują giją, sukuriame objektą Siūlas klasė. Jame naudojami parametrai „taikinys“ ir „args“. The taikinys yra funkcija, kurią turi atlikti gija, tuo tarpu args yra argumentai, kuriuos reikia perduoti tikslinei funkcijai.
t1 = threading.Thread(target, args) t2 = threading.Thread(target, args)>
3 veiksmas: Pradėti giją
Norėdami pradėti giją, naudojame pradžia () Thread klasės metodas.
t1.start() t2.start()>
4 veiksmas: Užbaikite giją Vykdymas
eilučių masyvei java
Pradėjus gijas, dabartinė programa (galite manyti, kad ji yra pagrindinė gija) taip pat toliau vykdoma. Norėdami sustabdyti dabartinės programos vykdymą, kol bus baigta gija, naudojame prisijungti () metodas.
t1.join() t2.join()>
Dėl to dabartinė programa pirmiausia lauks, kol bus baigta t1 ir tada t2 . Jiems pasibaigus, vykdomi likę dabartinės programos sakiniai.
Pavyzdys:
Panagrinėkime paprastą pavyzdį naudojant sriegimo modulį.
Šis kodas parodo, kaip naudoti Python sriegimo modulį, norint vienu metu apskaičiuoti skaičiaus kvadratą ir kubą. Du siūlai, t1> ir t2> , yra sukurti šiems skaičiavimams atlikti. Jie paleidžiami, o jų rezultatai spausdinami lygiagrečiai prieš programai išspausdinant Done! kai baigsis abi gijos. Sriegimas naudojamas norint pasiekti lygiagretumą ir pagerinti programos našumą atliekant sudėtingas skaičiavimo užduotis.
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!'>)> |
>
>
Išvestis:
kas yra hashset java
Square: 100 Cube: 1000 Done!>
Apsvarstykite toliau pateiktą diagramą, kad geriau suprastumėte, kaip veikia aukščiau nurodyta programa:

Daugiagija
Pavyzdys:
Šiame pavyzdyje mes naudojame os.getpid() funkcija gauti dabartinio proceso ID. Mes naudojame threading.main_thread() funkcija gauti pagrindinio gijos objektą. Įprastomis sąlygomis pagrindinė gija yra gija, iš kurios buvo paleistas Python interpretatorius. vardas gijos objekto atributas naudojamas gijos pavadinimui gauti. Tada mes naudojame threading.current_thread() funkcija gauti dabartinį gijos objektą.
Apsvarstykite toliau pateiktą Python programą, kurioje spausdiname kiekvienos užduoties gijos pavadinimą ir atitinkamą procesą.
Šis kodas parodo, kaip naudoti Python gijų modulį, kad vienu metu būtų galima vykdyti dvi užduotis. Pagrindinė programa inicijuoja dvi gijas, t1> ir t2> , kiekvienas atsakingas už konkrečios užduoties vykdymą. Gijos veikia lygiagrečiai, o kodas pateikia informaciją apie proceso ID ir gijų pavadinimus. Theos>modulis naudojamas norint pasiekti proceso ID, ir “ threading'> modulis naudojamas gijų ir jų vykdymo valdymui.
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()> |
>
>
Išvestis:
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>
Žemiau pateikta diagrama paaiškina aukščiau pateiktą koncepciją:

Daugiagija
Taigi, tai buvo trumpas įvadas į daugiagiją Python. Kitas šios serijos straipsnis apima sinchronizavimas tarp kelių gijų . Kelių gijų kūrimas Python | 2 rinkinys (sinchronizavimas)
Python ThreadPool
Gijų telkinys yra gijų rinkinys, kuris yra sukurtas iš anksto ir gali būti pakartotinai naudojamas kelioms užduotims atlikti. Python modulis concurrent.futures suteikia ThreadPoolExecutor klasę, kuri leidžia lengvai kurti ir valdyti gijų telkinį.
Šiame pavyzdyje apibrėžiame funkcijos darbuotoją, kuris veiks gijoje. Sukuriame ThreadPoolExecutor su daugiausia 2 darbininkų gijomis. Tada pateikiame dvi užduotis telkiniui naudodami pateikimo metodą. Baseinas valdo užduočių vykdymą savo darbuotojų gijose. Naudojame išjungimo metodą, kad palauktume, kol visos užduotys bus baigtos, kol pagrindinė gija tęsis.
Kelių gijų naudojimas gali padėti jūsų programas padaryti efektyvesnes ir jautresnes. Tačiau svarbu būti atsargiems dirbant su siūlais, kad išvengtumėte tokių problemų kaip lenktynių sąlygos ir aklavietės.
Šis kodas naudoja gijų telkinį, sukurtą su concurrent.futures.ThreadPoolExecutor> vienu metu vykdyti dvi darbuotojo užduotis. Pagrindinis siūlas laukia, kol darbuotojo gijos baigs naudoti pool.shutdown(wait=True)> . Tai leidžia efektyviai lygiagrečiai apdoroti užduotis kelių gijų aplinkoje.
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'>)> |
>
mesti išimties tvarkymą java
>Išvestis
Worker thread running Worker thread running Main thread continuing to run>