Denne artikkelen dekker det grunnleggende om multithreading i programmeringsspråket Python. Akkurat som multiprosessering , er multithreading en måte å oppnå multitasking på. I multithreading er begrepet tråder benyttes. La oss først forstå konseptet tråd i dataarkitektur.
Hva er en prosess i Python?
I databehandling, a prosess er en forekomst av et dataprogram som kjøres. Enhver prosess har 3 grunnleggende komponenter:
- Et kjørbart program.
- De tilknyttede dataene som trengs av programmet (variabler, arbeidsområde, buffere, etc.)
- Utførelseskonteksten til programmet (prosessens tilstand)
En introduksjon til Python Threading
EN tråd er en enhet innenfor en prosess som kan planlegges for utførelse. Det er også den minste prosesseringsenheten som kan utføres i et OS (operativsystem). Med enkle ord er en tråd en sekvens av slike instruksjoner i et program som kan kjøres uavhengig av annen kode. For enkelhets skyld kan du anta at en tråd ganske enkelt er en delmengde av en prosess! En tråd inneholder all denne informasjonen i en Trådkontrollblokk (TCB) :
- Trådidentifikator: Unik id (TID) tildeles hver ny tråd
- Stabelpeker: Peker på trådens stabel i prosessen. Stabelen inneholder de lokale variablene under trådens omfang.
- Programteller: et register som lagrer adressen til instruksjonen som for øyeblikket utføres av en tråd.
- Trådtilstand: kan være i gang, klar, venter, starter eller ferdig.
- Trådens registersett: registre tilordnet tråd for beregninger.
- Overordnet prosesspeker: En peker til prosesskontrollblokken (PCB) til prosessen som tråden lever av.
Vurder diagrammet nedenfor for å forstå forholdet mellom prosessen og dens tråd:

Forholdet mellom en prosess og dens tråd
Flere tråder kan eksistere i én prosess der:
- Hver tråd inneholder sin egen register sett og lokale variabler (lagret i stabelen) .
- Alle tråder i en prosess deler globale variabler (lagret i haug) og programkode .
Vurder diagrammet nedenfor for å forstå hvordan flere tråder eksisterer i minnet:

Eksistensen av flere tråder i minnet
En introduksjon til tråding i Python
Multithreading er definert som evnen til en prosessor til å kjøre flere tråder samtidig. I en enkel CPU med én kjerne oppnås det ved å bruke hyppig veksling mellom tråder. Dette kalles kontekstbytte . I kontekstbytte lagres tilstanden til en tråd, og tilstanden til en annen tråd lastes inn hver gang et avbrudd (på grunn av I/O eller manuelt innstilt) finner sted. Kontekstbytte finner sted så ofte at alle trådene ser ut til å kjøre parallelt (dette kalles multitasking ).
Tenk på diagrammet nedenfor der en prosess inneholder to aktive tråder:

Multithreading
Multithreading i Python
I Python , den tråding modulen gir et veldig enkelt og intuitivt API for å skape flere tråder i et program. La oss prøve å forstå multithreading-kode trinn for trinn.
Trinn 1: Importmodul
Først importerer du trådmodulen.
import threading>
Steg 2: Lag en tråd
For å lage en ny tråd, lager vi et objekt av Tråd klasse. Den tar 'mål' og 'args' som parametere. De mål er funksjonen som skal utføres av tråden mens args er argumentene som skal sendes til målfunksjonen.
t1 = threading.Thread(target, args) t2 = threading.Thread(target, args)>
Trinn 3: Start en tråd
For å starte en tråd bruker vi start() metoden til Thread-klassen.
t1.start() t2.start()>
Trinn 4: Avslutt trådutførelsen
Når trådene starter, fortsetter også det gjeldende programmet (du kan tenke på det som en hovedtråd) å kjøre. For å stoppe kjøringen av gjeldende program til en tråd er fullført, bruker vi bli med() metode.
t1.join() t2.join()>
Som et resultat vil det nåværende programmet først vente på fullføring av t1 og så t2 . Når de er ferdige, blir de resterende setningene i det gjeldende programmet utført.
Eksempel:
La oss vurdere et enkelt eksempel ved å bruke en gjengemodul.
Denne koden viser hvordan du bruker Pythons trådmodul for å beregne kvadratet og terningen til et tall samtidig. To tråder, t1> og t2> , opprettes for å utføre disse beregningene. De startes, og resultatene deres skrives ut parallelt før programmet skrives ut Ferdig! når begge trådene er ferdige. Tråding brukes for å oppnå parallellitet og forbedre programytelsen når man arbeider med beregningsintensive oppgaver.
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!'>)> |
>
>
arp en kommando
Produksjon:
Square: 100 Cube: 1000 Done!>
Vurder diagrammet nedenfor for en bedre forståelse av hvordan programmet ovenfor fungerer:

Multithreading
Eksempel:
I dette eksemplet bruker vi os.getpid() funksjon for å få IDen til gjeldende prosess. Vi bruker threading.main_thread() funksjon for å hente hovedtrådsobjektet. Under normale forhold er hovedtråden tråden som Python-tolken ble startet fra. Navn attributtet til trådobjektet brukes for å få navnet på tråden. Da bruker vi threading.current_thread() funksjon for å hente gjeldende trådobjekt.
Tenk på Python-programmet gitt nedenfor der vi skriver ut trådnavnet og tilsvarende prosess for hver oppgave.
Denne koden viser hvordan du bruker Pythons trådmodul for å kjøre to oppgaver samtidig. Hovedprogrammet starter to tråder, t1> og t2> , hver ansvarlig for å utføre en spesifikk oppgave. Trådene går parallelt, og koden gir informasjon om prosess-ID og trådnavn. Deos>modulen brukes til å få tilgang til prosess-ID, og ' threading'> modulen brukes til å administrere tråder og deres utfø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()> |
>
>
Produksjon:
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 fjerner konseptet ovenfor:

Multithreading
Så dette var en kort introduksjon til multithreading i Python. Den neste artikkelen i denne serien dekker synkronisering mellom flere tråder . Multithreading i Python | Sett 2 (synkronisering)
Python ThreadPool
En trådpool er en samling tråder som er opprettet på forhånd og kan gjenbrukes til å utføre flere oppgaver. Concurrent.futures-modulen i Python gir en ThreadPoolExecutor-klasse som gjør det enkelt å opprette og administrere en trådpool.
I dette eksemplet definerer vi en funksjonsarbeider som skal kjøres i en tråd. Vi lager en ThreadPoolExecutor med maksimalt 2 arbeidertråder. Vi sender deretter inn to oppgaver til bassenget ved hjelp av innsendingsmetoden. Bassenget styrer utførelsen av oppgavene i sine arbeidertråder. Vi bruker avslutningsmetoden for å vente på at alle oppgaver er fullført før hovedtråden fortsetter.
Multithreading kan hjelpe deg med å gjøre programmene dine mer effektive og responsive. Det er imidlertid viktig å være forsiktig når du arbeider med tråder for å unngå problemer som løpsforhold og vranglås.
Denne koden bruker en trådpool opprettet med concurrent.futures.ThreadPoolExecutor> å kjøre to arbeidsoppgaver samtidig. Hovedtråden venter på at arbeidertrådene er ferdige å bruke pool.shutdown(wait=True)> . Dette gir mulighet for effektiv parallell behandling av oppgaver i et flertrådsmiljø.
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'>)> |
>
>Produksjon
Worker thread running Worker thread running Main thread continuing to run>