logo

Multithreading v Pythonu

Tento článek popisuje základy multithreadingu v programovacím jazyce Python. Stejně jako multiprocessing , multithreading je způsob, jak dosáhnout multitaskingu. V multithreadingu, koncept vlákna se používá. Pojďme nejprve pochopit koncept vlákno v počítačové architektuře.

Co je to proces v Pythonu?

V oblasti výpočetní techniky a proces je instancí počítačového programu, který se spouští. Každý proces má 3 základní složky:



  • Spustitelný program.
  • Přidružená data potřebná pro program (proměnné, pracovní prostor, vyrovnávací paměti atd.)
  • Kontext provádění programu (stav procesu)

Úvod do Python Threading

A vlákno je entita v rámci procesu, jejíž provedení lze naplánovat. Je to také nejmenší jednotka zpracování, kterou lze provést v operačním systému (Operating System). Jednoduše řečeno, vlákno je posloupnost takových instrukcí v programu, kterou lze spustit nezávisle na jiném kódu. Pro jednoduchost můžete předpokládat, že vlákno je jednoduše podmnožinou procesu! Vlákno obsahuje všechny tyto informace v a Blok řízení závitů (TCB) :

  • Identifikátor vlákna: Každému novému vláknu je přiřazeno jedinečné ID (TID).
  • Ukazatel zásobníku: Ukazuje na zásobník vlákna v procesu. Zásobník obsahuje lokální proměnné v rozsahu vlákna.
  • Počítadlo programů: registr, který ukládá adresu instrukce aktuálně prováděné vláknem.
  • Stav vlákna: může být spuštěný, připravený, čekající, spouštěný nebo hotový.
  • Sada registru vláken: registry přiřazené vláknu pro výpočty.
  • Ukazatel nadřazeného procesu: Ukazatel na řídicí blok procesu (PCB) procesu, na kterém vlákno žije.

Zvažte níže uvedený diagram, abyste pochopili vztah mezi procesem a jeho vláknem:

multithreading-python-11

Vztah mezi procesem a jeho vláknem



V rámci jednoho procesu může existovat více vláken, kde:

  • Každé vlákno obsahuje své vlastní sada registrů a lokální proměnné (uložené v zásobníku) .
  • Všechna vlákna procesu sdílejí globální proměnné (uložené na hromadě) a programový kód .

Zvažte níže uvedený diagram, abyste pochopili, jak v paměti existuje více vláken:

multithreading-python-21

Existence více vláken v paměti



Úvod do Threading v Pythonu

Vícevláknové zpracování je definována jako schopnost procesoru spouštět více vláken současně. V jednoduchém jednojádrovém CPU je toho dosaženo pomocí častého přepínání mezi vlákny. Toto se nazývá přepínání kontextu . Při přepínání kontextu se stav vlákna uloží a stav jiného vlákna se načte vždy, když dojde k jakémukoli přerušení (kvůli I/O nebo ručně nastavenému). Přepínání kontextu probíhá tak často, že se zdá, že všechna vlákna běží paralelně (toto se nazývá multitasking ).

Zvažte níže uvedený diagram, ve kterém proces obsahuje dvě aktivní vlákna:

multithreading-python-31

Vícevláknové zpracování

Multithreading v Pythonu

v Krajta , závitování modul poskytuje velmi jednoduché a intuitivní API pro vytváření více vláken v programu. Pokusme se porozumět vícevláknovému kódu krok za krokem.

Krok 1: Import modulu

Nejprve importujte modul závitování.

import threading>

Krok 2: Vytvořte vlákno

Pro vytvoření nového vlákna vytvoříme objekt Vlákno třída. Jako parametry bere ‚target‘ a ‚args‘. The cílová je funkce, kterou má vlákno provést, zatímco args je argumenty, které mají být předány cílové funkci.

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

Krok 3: Spusťte vlákno

K zahájení vlákna použijeme Start() metoda třídy Thread.

t1.start() t2.start()>

Krok 4: Ukončete provádění vlákna

Jakmile se vlákna spustí, aktuální program (můžete si to představit jako hlavní vlákno) také pokračuje v provádění. Abychom zastavili provádění aktuálního programu, dokud není vlákno dokončeno, používáme připojit se() metoda.

t1.join() t2.join()>

V důsledku toho bude aktuální program nejprve čekat na dokončení t1 a pak t2 . Jakmile jsou dokončeny, provedou se zbývající příkazy aktuálního programu.

Příklad:

jak získat emodži iphone na android

Uvažujme jednoduchý příklad s použitím modulu závitování.

Tento kód ukazuje, jak používat modul vláken Pythonu k současnému výpočtu druhé mocniny a krychle čísla. dvě vlákna, t1> a t2> , jsou vytvořeny pro provádění těchto výpočtů. Jsou spuštěny a jejich výsledky jsou vytištěny paralelně před tiskem programu Hotovo! až skončí obě vlákna. Threading se používá k dosažení paralelismu a zlepšení výkonu programu při řešení výpočetně náročných úloh.

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

>

>

Výstup:

Square: 100 Cube: 1000 Done!>

Zvažte níže uvedený diagram pro lepší pochopení toho, jak výše uvedený program funguje:

multithreading-python-4

Vícevláknové zpracování

Příklad:

kolik měst je ve Spojených státech

V tomto příkladu používáme os.getpid() k získání ID aktuálního procesu. Používáme threading.main_thread() funkce pro získání objektu hlavního vlákna. Za normálních podmínek je hlavním vláknem vlákno, ze kterého byl spuštěn interpret Pythonu. název atribut objektu vlákna se používá k získání názvu vlákna. Poté použijeme threading.current_thread() funkce pro získání aktuálního objektu vlákna.

Zvažte program Python uvedený níže, ve kterém vytiskneme název vlákna a odpovídající proces pro každou úlohu.

Tento kód ukazuje, jak používat modul vláken Pythonu ke spouštění dvou úloh současně. Hlavní program spustí dvě vlákna, t1> a t2> , z nichž každý odpovídá za provedení konkrétního úkolu. Vlákna běží paralelně a kód poskytuje informace o ID procesu a názvech vláken. Theos>modul se používá pro přístup k ID procesu a ' threading'> modul se používá ke správě vláken a jejich provádění.

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

odstranit první znak excel
>

>

Výstup:

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>

Níže uvedený diagram objasňuje výše uvedený koncept:

multithreading-python-5

Vícevláknové zpracování

Toto byl krátký úvod do multithreadingu v Pythonu. Další článek této série se týká synchronizace mezi více vlákny . Multithreading v Pythonu | Sada 2 (synchronizace)

Python ThreadPool

Fond vláken je kolekce vláken, která jsou vytvořena předem a lze je znovu použít k provádění více úloh. Modul concurrent.futures v Pythonu poskytuje třídu ThreadPoolExecutor, která usnadňuje vytváření a správu fondu vláken.

V tomto příkladu definujeme funkčního pracovníka, který poběží ve vláknu. Vytváříme ThreadPoolExecutor s maximálně 2 pracovními vlákny. Poté předáme dva úkoly do fondu pomocí metody odeslání. Fond spravuje provádění úloh ve svých pracovních vláknech. Metodu vypnutí používáme k čekání na dokončení všech úkolů, než bude pokračovat hlavní vlákno.

Vícevláknové zpracování vám může pomoci učinit vaše programy efektivnějšími a pohotovějšími. Při práci s vlákny je však důležité být opatrní, abyste se vyhnuli problémům, jako jsou podmínky závodu a uváznutí.

Tento kód používá fond vláken vytvořený pomocí concurrent.futures.ThreadPoolExecutor> spouštět dvě pracovní úlohy současně. Hlavní vlákno čeká, až pracovní vlákna dokončí používání pool.shutdown(wait=True)> . To umožňuje efektivní paralelní zpracování úloh ve vícevláknovém prostředí.

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

>

>

Výstup

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