logo

Multithreading i Python

Denne artikel dækker det grundlæggende i multithreading i Python-programmeringssproget. Ligesom multibearbejdning , er multithreading en måde at opnå multitasking på. I multithreading er begrebet tråde anvendes. Lad os først forstå begrebet tråd i computerarkitektur.

Hvad er en proces i Python?

Inden for databehandling, en behandle er en forekomst af et computerprogram, der udføres. Enhver proces har 3 grundlæggende komponenter:



  • Et eksekverbart program.
  • De tilknyttede data, der kræves af programmet (variabler, arbejdsområde, buffere osv.)
  • Udførelseskonteksten for programmet (Status af processen)

En introduktion til Python Threading

EN tråd er en enhed i en proces, der kan planlægges til udførelse. Det er også den mindste behandlingsenhed, der kan udføres i et OS (operativsystem). Med enkle ord er en tråd en sekvens af sådanne instruktioner i et program, der kan udføres uafhængigt af anden kode. For nemheds skyld kan du antage, at en tråd blot er en delmængde af en proces! En tråd indeholder alle disse oplysninger i en Trådkontrolblok (TCB) :

  • Trådidentifikator: Unikt id (TID) tildeles hver ny tråd
  • Stakmarkør: Peger på trådens stak i processen. Stakken indeholder de lokale variabler under trådens omfang.
  • Programtæller: et register, der gemmer adressen på den instruktion, der i øjeblikket udføres af en tråd.
  • Trådtilstand: kan være kørende, klar, venter, starter eller færdig.
  • Trådens registersæt: registre tildelt tråd til beregninger.
  • Overordnet proces pointer: En pegepind til proceskontrolblokken (PCB) for den proces, som tråden lever af.

Overvej diagrammet nedenfor for at forstå forholdet mellem processen og dens tråd:

multithreading-python-11

Forholdet mellem en proces og dens tråd



Der kan eksistere flere tråde i én proces, hvor:

  • Hver tråd indeholder sin egen register sæt og lokale variabler (gemt i stakken) .
  • Alle tråde i en proces deler globale variabler (gemt i heap) og programkode .

Overvej diagrammet nedenfor for at forstå, hvordan flere tråde eksisterer i hukommelsen:

multithreading-python-21

Eksistensen af ​​flere tråde i hukommelsen



En introduktion til trådning i Python

Multithreading er defineret som en processors evne til at udføre flere tråde samtidigt. I en enkel, single-core CPU opnås det ved hjælp af hyppig skift mellem tråde. Dette kaldes kontekstskifte . Ved kontekstskift gemmes tilstanden af ​​en tråd, og tilstanden for en anden tråd indlæses, hver gang en afbrydelse (på grund af I/O eller manuelt indstillet) finder sted. Kontekstskift finder sted så ofte, at alle tråde ser ud til at køre parallelt (dette kaldes multitasking ).

Overvej diagrammet nedenfor, hvor en proces indeholder to aktive tråde:

multithreading-python-31

Multithreading

Multithreading i Python

I Python , det trådning modul giver en meget enkel og intuitiv API til at skabe flere tråde i et program. Lad os prøve at forstå multithreading-kode trin for trin.

Trin 1: Import modul

Importer først trådningsmodulet.

import threading>

Trin 2: Opret en tråd

For at oprette en ny tråd opretter vi et objekt af Tråd klasse. Det tager 'mål' og 'args' som parametre. Det mål er den funktion, der skal udføres af tråden, hvorimod args er argumenterne, der skal sendes til målfunktionen.

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

Trin 3: Start en tråd

For at starte en tråd bruger vi Start() metode i trådklassen.

t1.start() t2.start()>

Trin 4: Afslut trådens udførelse

Når trådene starter, fortsætter det aktuelle program (du kan tænke på det som en hovedtråd) også med at køre. For at stoppe udførelsen af ​​det aktuelle program, indtil en tråd er færdig, bruger vi tilslutte() metode.

t1.join() t2.join()>

Som følge heraf vil det nuværende program først vente på afslutningen af t1 og så t2 . Når de er færdige, udføres de resterende udsagn af det aktuelle program.

Eksempel:

Lad os overveje et simpelt eksempel ved hjælp af et gevindmodul.

Denne kode demonstrerer, hvordan man bruger Pythons threading-modul til at beregne kvadratet og terningen af ​​et tal samtidigt. To tråde, t1> og t2> , oprettes for at udføre disse beregninger. De startes, og deres resultater udskrives parallelt, inden programmet udskriver Udført! når begge tråde er færdige. Threading bruges til at opnå parallelitet og forbedre programmets ydeevne, når man håndterer beregningsintensive opgaver.

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

>

>

dobbelt i java

Produktion:

Square: 100 Cube: 1000 Done!>

Overvej diagrammet nedenfor for en bedre forståelse af, hvordan ovenstående program fungerer:

multithreading-python-4

Multithreading

Eksempel:

I dette eksempel bruger vi os.getpid() funktion for at få ID'et for den aktuelle proces. Vi bruger threading.main_thread() funktion for at hente hovedtrådsobjektet. Under normale forhold er hovedtråden den tråd, hvorfra Python-fortolkeren blev startet. navn attributten for trådobjektet bruges til at få navnet på tråden. Så bruger vi threading.current_thread() funktion for at hente det aktuelle trådobjekt.

Overvej Python-programmet nedenfor, hvor vi udskriver trådnavnet og den tilsvarende proces for hver opgave.

Denne kode demonstrerer, hvordan man bruger Pythons threading-modul til at køre to opgaver samtidigt. Hovedprogrammet starter to tråde, t1> og t2> , hver ansvarlig for at udføre en bestemt opgave. Trådene kører parallelt, og koden giver information om proces-id og trådnavne. Detos>modul bruges til at få adgang til proces-id'et og ' threading'> modul bruges til at styre tråde og deres udførelse.

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

>

>

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 nedenfor rydder ovenstående koncept:

multithreading-python-5

Multithreading

Så dette var en kort introduktion til multithreading i Python. Den næste artikel i denne serie dækker synkronisering mellem flere tråde . Multithreading i Python | Sæt 2 (synkronisering)

Python ThreadPool

En trådpulje er en samling af tråde, der er oprettet på forhånd og kan genbruges til at udføre flere opgaver. Concurrent.futures-modulet i Python giver en ThreadPoolExecutor-klasse, der gør det nemt at oprette og administrere en trådpulje.

I dette eksempel definerer vi en funktionsarbejder, der skal køre i en tråd. Vi opretter en ThreadPoolExecutor med maksimalt 2 arbejdstråde. Derefter afleverer vi to opgaver til puljen ved hjælp af afleveringsmetoden. Puljen styrer udførelsen af ​​opgaverne i sine arbejdertråde. Vi bruger nedlukningsmetoden til at vente på, at alle opgaver er fuldført, før hovedtråden fortsætter.

Multithreading kan hjælpe dig med at gøre dine programmer mere effektive og responsive. Det er dog vigtigt at være forsigtig, når du arbejder med tråde, for at undgå problemer som racerforhold og dødvande.

Denne kode bruger en trådpulje oprettet med concurrent.futures.ThreadPoolExecutor> at køre to arbejderopgaver samtidigt. Hovedtråden venter på, at arbejdertrådene er færdige med at bruge pool.shutdown(wait=True)> . Dette giver mulighed for effektiv parallel behandling af opgaver i et multi-threaded 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>