logo

Multithreading i Python

Den här artikeln täcker grunderna för multithreading i programmeringsspråket Python. Precis som multibearbetning , multithreading är ett sätt att uppnå multitasking. I multithreading, begreppet trådar är använd. Låt oss först förstå begreppet tråd inom datorarkitektur.

pd sammanfoga

Vad är en process i Python?

Inom datorer, a bearbeta är en instans av ett datorprogram som körs. Varje process har 3 grundläggande komponenter:



  • Ett körbart program.
  • De associerade data som behövs av programmet (variabler, arbetsyta, buffertar, etc.)
  • Programmets exekveringskontext (processens tillstånd)

En introduktion till Python Threading

A tråd är en enhet inom en process som kan schemaläggas för exekvering. Det är också den minsta bearbetningsenheten som kan utföras i ett operativsystem (operativsystem). Med enkla ord är en tråd en sekvens av sådana instruktioner i ett program som kan exekveras oberoende av annan kod. För enkelhetens skull kan du anta att en tråd helt enkelt är en delmängd av en process! En tråd innehåller all denna information i en Trådkontrollblock (TCB) :

  • Trådidentifierare: Unikt id (TID) tilldelas varje ny tråd
  • Stackpekare: Pekar på trådens stack i processen. Stacken innehåller de lokala variablerna under trådens räckvidd.
  • Programräknare: ett register som lagrar adressen till den instruktion som för närvarande exekveras av en tråd.
  • Trådstatus: kan vara igång, redo, väntande, startande eller klar.
  • Trådens registeruppsättning: register tilldelade till tråd för beräkningar.
  • Föräldraprocesspekare: En pekare till processkontrollblocket (PCB) för processen som tråden lever på.

Betrakta diagrammet nedan för att förstå förhållandet mellan processen och dess tråd:

multithreading-python-11

Förhållandet mellan en process och dess tråd



Flera trådar kan finnas inom en process där:

  • Varje tråd innehåller sin egen registeruppsättning och lokala variabler (lagrade i stacken) .
  • Alla trådar i en process delar globala variabler (lagrade i hög) och den programkod .

Betrakta diagrammet nedan för att förstå hur flera trådar finns i minnet:

multithreading-python-21

Förekomsten av flera trådar i minnet



En introduktion till trådning i Python

Multithreading definieras som förmågan hos en processor att köra flera trådar samtidigt. I en enkel, enkärnig CPU, uppnås det genom att ofta växla mellan trådar. Detta kallas kontextbyte . Vid kontextväxling sparas tillståndet för en tråd och tillståndet för en annan tråd laddas närhelst något avbrott (på grund av I/O eller manuellt inställt) äger rum. Kontextväxling sker så ofta att alla trådar verkar köra parallellt (detta kallas göra flera saker samtidigt ).

Betrakta diagrammet nedan där en process innehåller två aktiva trådar:

multithreading-python-31

Multithreading

Multithreading i Python

I Pytonorm , den gängning modulen tillhandahåller ett mycket enkelt och intuitivt API för att skapa flera trådar i ett program. Låt oss försöka förstå flertrådskod steg för steg.

Steg 1: Importmodul

Importera först gängningsmodulen.

import threading>

Steg 2: Skapa en tråd

För att skapa en ny tråd skapar vi ett objekt av Tråd klass. Det tar 'mål' och 'args' som parametrar. De mål är funktionen som ska köras av tråden medan args är argumenten som ska skickas till målfunktionen.

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

Steg 3: Starta en tråd

För att starta en tråd använder vi Start() metod för klassen Thread.

t1.start() t2.start()>

Steg 4: Avsluta tråden Execution

När trådarna väl startar fortsätter det aktuella programmet (du kan se det som en huvudtråd) också att köras. För att stoppa exekveringen av det aktuella programmet tills en tråd är klar använder vi Ansluta sig() metod.

t1.join() t2.join()>

Som ett resultat kommer det nuvarande programmet först att vänta på att slutförandet av t1 och då t2 . När de är klara exekveras de återstående satserna i det aktuella programmet.

Exempel:

Låt oss överväga ett enkelt exempel med en gängningsmodul.

Den här koden visar hur man använder Pythons gängningsmodul för att beräkna kvadraten och kuben för ett tal samtidigt. Två trådar, t1> och t2> , skapas för att utföra dessa beräkningar. De startas och deras resultat skrivs ut parallellt innan programmet skrivs ut Klart! när båda trådarna är slut. Trådning används för att uppnå parallellitet och förbättra programprestanda när man hanterar beräkningsintensiva uppgifter.

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

>

>

Produktion:

Square: 100 Cube: 1000 Done!>

Tänk på diagrammet nedan för en bättre förståelse av hur ovanstående program fungerar:

multithreading-python-4

Multithreading

Exempel:

I det här exemplet använder vi os.getpid() funktion för att få ID för den aktuella processen. Vi använder threading.main_thread() funktion för att hämta huvudtrådsobjektet. Under normala förhållanden är huvudtråden tråden från vilken Python-tolken startades. namn attributet för trådobjektet används för att få namnet på tråden. Då använder vi threading.current_thread() funktion för att hämta det aktuella trådobjektet.

Tänk på Python-programmet nedan där vi skriver ut trådnamnet och motsvarande process för varje uppgift.

Den här koden visar hur man använder Pythons trådningsmodul för att köra två uppgifter samtidigt. Huvudprogrammet initierar två trådar, t1> och t2> , var och en ansvarig för att utföra en specifik uppgift. Trådarna löper parallellt och koden ger information om process-ID och trådnamn. Deos>modulen används för att komma åt process-ID och ' threading'> modulen används för att hantera trådar och deras exekvering.

strsep c

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

>

>

mikrolitisk kärna

Produktion:

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>

Diagrammet nedan rensar konceptet ovan:

multithreading-python-5

Multithreading

Så detta var en kort introduktion till multithreading i Python. Nästa artikel i den här serien tar upp synkronisering mellan flera trådar . Multithreading i Python | Set 2 (synkronisering)

Python ThreadPool

En trådpool är en samling trådar som skapas i förväg och som kan återanvändas för att utföra flera uppgifter. Modulen concurrent.futures i Python tillhandahåller en ThreadPoolExecutor-klass som gör det enkelt att skapa och hantera en trådpool.

I det här exemplet definierar vi en funktionsarbetare som körs i en tråd. Vi skapar en ThreadPoolExecutor med maximalt 2 arbetartrådar. Vi lämnar sedan in två uppgifter till poolen med hjälp av inlämningsmetoden. Poolen hanterar utförandet av uppgifterna i sina arbetartrådar. Vi använder avstängningsmetoden för att vänta på att alla uppgifter är klara innan huvudtråden fortsätter.

Multithreading kan hjälpa dig att göra dina program mer effektiva och lyhörda. Det är dock viktigt att vara försiktig när du arbetar med trådar för att undvika problem som tävlingsförhållanden och dödlägen.

Den här koden använder en trådpool skapad med concurrent.futures.ThreadPoolExecutor> att köra två arbetsuppgifter samtidigt. Huvudtråden väntar på att arbetartrådarna ska slutföras pool.shutdown(wait=True)> . Detta möjliggör effektiv parallell bearbetning av uppgifter i en flertrådig miljö.

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

>

>

Produktion

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