logo

Multithreading v Pythone

Tento článok sa zaoberá základmi multithreadingu v programovacom jazyku Python. Rovnako ako multiprocessing , multithreading je spôsob dosiahnutia multitaskingu. V multithreadingu je koncept vlákna sa používa. Poďme najprv pochopiť pojem niť v počítačovej architektúre.

Čo je to proces v Pythone?

V oblasti výpočtovej techniky a proces je inštancia počítačového programu, ktorý sa práve vykonáva. Každý proces má 3 základné zložky:



  • Spustiteľný program.
  • Súvisiace údaje potrebné pre program (premenné, pracovný priestor, vyrovnávacie pamäte atď.)
  • Kontext vykonávania programu (Stav procesu)

Úvod do Python Threading

A niť je entita v rámci procesu, ktorej vykonanie možno naplánovať. Je to tiež najmenšia jednotka spracovania, ktorú je možné vykonať v operačnom systéme (OS). Jednoducho povedané, vlákno je sekvencia takýchto inštrukcií v rámci programu, ktorá môže byť vykonaná nezávisle od iného kódu. Pre jednoduchosť môžete predpokladať, že vlákno je jednoducho podmnožinou procesu! Vlákno obsahuje všetky tieto informácie v a Blok riadenia závitov (TCB) :

  • Identifikátor vlákna: Jedinečné ID (TID) je priradené každému novému vláknu
  • Ukazovateľ zásobníka: Ukazuje na zásobník vlákna v procese. Zásobník obsahuje lokálne premenné v rozsahu vlákna.
  • Počítadlo programov: register, ktorý ukladá adresu inštrukcie, ktorú vlákno práve vykonáva.
  • Stav vlákna: môže byť spustený, pripravený, čakajúci, spustený alebo hotový.
  • Súprava registrov vlákien: registre priradené k vláknu na výpočty.
  • Ukazovateľ nadradeného procesu: Ukazovateľ na riadiaci blok procesu (PCB) procesu, na ktorom vlákno žije.

Zvážte nižšie uvedený diagram, aby ste pochopili vzťah medzi procesom a jeho vláknom:

multithreading-python-11

Vzťah medzi procesom a jeho vláknom



V rámci jedného procesu môže existovať viacero vlákien, kde:

  • Každé vlákno obsahuje svoje vlastné súbor registrov a lokálne premenné (uložené v zásobníku) .
  • Všetky vlákna procesu zdieľajú globálne premenné (uložené v halde) a programový kód .

Zvážte nižšie uvedený diagram, aby ste pochopili, ako v pamäti existuje viacero vlákien:

repl v jave
multithreading-python-21

Existencia viacerých vlákien v pamäti



Úvod do Threading v Pythone

Multithreading je definovaná ako schopnosť procesora vykonávať viacero vlákien súčasne. V jednoduchom jednojadrovom CPU sa to dosahuje pomocou častého prepínania medzi vláknami. Toto sa nazýva prepínanie kontextu . Pri prepínaní kontextu sa stav vlákna uloží a stav iného vlákna sa načíta vždy, keď dôjde k akémukoľvek prerušeniu (kvôli I/O alebo manuálne nastavenému). Prepínanie kontextu prebieha tak často, že sa zdá, že všetky vlákna bežia paralelne (toto sa nazýva multitasking ).

Zvážte nižšie uvedený diagram, v ktorom proces obsahuje dve aktívne vlákna:

multithreading-python-31

Multithreading

Multithreading v Pythone

In Python , závitovanie modul poskytuje veľmi jednoduché a intuitívne API na vytváranie viacerých vlákien v programe. Pokúsme sa porozumieť viacvláknovému kódu krok za krokom.

Krok 1: Importovať modul

Najprv importujte modul závitovania.

import threading>

Krok 2: Vytvorte vlákno

Na vytvorenie nového vlákna vytvoríme objekt z Niť trieda. Ako parametre berie „cieľ“ a „argumenty“. The cieľ je funkcia, ktorú má vlákno vykonať, zatiaľ čo args je argumenty, ktoré sa majú odovzdať cieľovej funkcii.

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

Krok 3: Začať vlákno

Na spustenie vlákna používame začať () metóda triedy Thread.

java fazuľa
t1.start() t2.start()>

Krok 4: Ukončite vlákno Execution

Akonáhle sa vlákna spustia, aktuálny program (môžete si to predstaviť ako hlavné vlákno) tiež pokračuje v vykonávaní. Aby sme zastavili vykonávanie aktuálneho programu, kým sa vlákno nedokončí, používame pripojiť sa () metóda.

t1.join() t2.join()>

V dôsledku toho bude aktuálny program najskôr čakať na dokončenie t1 a potom t2 . Po ich dokončení sa vykonajú zostávajúce príkazy aktuálneho programu.

Príklad:

Uvažujme jednoduchý príklad s použitím modulu závitovania.

Tento kód ukazuje, ako používať modul vlákna Pythonu na súčasný výpočet druhej mocniny a kocky čísla. Dve vlákna, t1> a t2> , sú vytvorené na vykonávanie týchto výpočtov. Spustia sa a ich výsledky sa vytlačia paralelne pred tlačou programu Hotovo! keď obe vlákna skončia. Threading sa používa na dosiahnutie paralelizmu a zlepšenie výkonu programu pri riešení výpočtovo náročných úloh.

Python3




čo je gb

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!'>)>

>

>

Výkon:

Square: 100 Cube: 1000 Done!>

Zvážte nižšie uvedený diagram, aby ste lepšie pochopili, ako vyššie uvedený program funguje:

multithreading-python-4

Multithreading

Príklad:

V tomto príklade používame os.getpid() získajte ID aktuálneho procesu. Používame threading.main_thread() funkcia na získanie objektu hlavného vlákna. Za normálnych podmienok je hlavným vláknom vlákno, z ktorého bol spustený interpret Pythonu. názov atribút objektu vlákna sa používa na získanie názvu vlákna. Potom použijeme threading.current_thread() funkcia na získanie aktuálneho objektu vlákna.

Zvážte program Python uvedený nižšie, v ktorom vytlačíme názov vlákna a zodpovedajúci proces pre každú úlohu.

Tento kód ukazuje, ako používať modul vlákna Pythonu na spustenie dvoch úloh súčasne. Hlavný program spustí dve vlákna, t1> a t2> , z ktorých každý zodpovedá za vykonanie konkrétnej úlohy. Vlákna bežia paralelne a kód poskytuje informácie o ID procesu a názvoch vlákien. Theos>modul sa používa na prístup k ID procesu a ' threading'> modul sa používa na správu vlákien a ich spúšťanie.

Python3

dlhý na reťazec java




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()>

>

>

Výkon:

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>

Nižšie uvedený diagram objasňuje vyššie uvedený koncept:

multithreading-python-5

Multithreading

Toto bol krátky úvod do multithreadingu v Pythone. Ďalší článok z tejto série sa týka synchronizácia medzi viacerými vláknami . Multithreading v Pythone | Sada 2 (synchronizácia)

Python ThreadPool

Oblasť vlákien je kolekcia vlákien, ktoré sú vytvorené vopred a možno ich znova použiť na vykonávanie viacerých úloh. Modul concurrent.futures v Pythone poskytuje triedu ThreadPoolExecutor, ktorá uľahčuje vytváranie a správu oblasti vlákien.

V tomto príklade definujeme funkčného pracovníka, ktorý bude bežať vo vlákne. Vytvárame ThreadPoolExecutor s maximálne 2 pracovnými vláknami. Potom odošleme dve úlohy do skupiny pomocou metódy odovzdania. Fond riadi vykonávanie úloh vo svojich pracovných vláknach. Metódu vypnutia používame na čakanie na dokončenie všetkých úloh pred pokračovaním hlavného vlákna.

Multithreading vám môže pomôcť zefektívniť a reagovať na vaše programy. Pri práci s vláknami je však dôležité dávať pozor, aby ste sa vyhli problémom, ako sú podmienky pretekov a uviaznutie.

Tento kód používa fond vlákien vytvorený pomocou concurrent.futures.ThreadPoolExecutor> na spustenie dvoch pracovných úloh súčasne. Hlavné vlákno čaká, kým pracovné vlákna dokončia používanie pool.shutdown(wait=True)> . To umožňuje efektívne paralelné spracovanie úloh vo viacvláknovom prostredí.

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'>)>

stiahnite si video z youtube vlc
>

>

Výkon

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