Multiprocessing-pakken støtter gyteprosesser ved hjelp av en API lik trådemodulen. Det tilbyr også både lokal og ekstern samtidighet. Denne opplæringen vil diskutere multiprosessering i Python og hvordan du bruker multiprocessing til å kommunisere mellom prosesser og utføre synkronisering mellom prosesser, samt logging.
Multiprosessering fungerer ved å opprette en Prosess
objekt og deretter ringe det start()
metode som vist nedenfor.
fra multiprocessing import Process def greeting (): skriv ut 'hallo verden' hvis __name__ == '__main__': p = Prosess (mål = hilsen) p.start () p.join ()
I eksempelkoden ovenfor importerer vi først Prosess-klassen, og deretter ordner Prosessobjektet med hilsen-funksjonen som vi ønsker å kjøre.
Vi forteller deretter prosessen til å begynne å bruke start()
metode, og vi fullfører ferdig prosessen med bli med()
metode.
I tillegg kan du også sende argumenter til funksjonen ved å gi args
søkeordargument som slik:
fra multiprosessing import Prosesshilsen (navn): skriv ut 'hallo' + "" + navn hvis __name__ == '__main__': p = Prosess (mål = hilsen, args = ('verden')) p.start .bli med()
La oss se på et mer detaljert eksempel som dekker alle konseptene vi har diskutert ovenfor.
I dette eksemplet skal vi lage en prosess som beregner tallet av tall og skriver resultatene til konsollen.
fra multiprocessing import Prosess def kvadrat (x): for x i tall: print ('% s squared er% s'% (x, x ** 2)) hvis __name__ == '__main__': tall = [43, 50, 5, 98, 34, 35] p = Prosess (mål = kvadrat, args = ('x')) p.start () p.join print "Ferdig" #result Ferdig 43 kvadrert er 1849 50 kvadrert er 2500 5 kvadrert er 25 98 kvadrat er 9604 34 kvadrat er 1156 35 kvadrat er 1225
Du kan også opprette flere prosesser samtidig, som vist i eksempelet nedenfor, i hvilken prosess p1 får resultatene av tallene kvadratet, mens den andre prosessen p2 sjekker om de oppgitte tallene er like.
fra multiprocessing import Prosess def kvadrat (x): for x i tall: print ('% s kvadrat er% s'% (x, x ** 2)) def is_even (x): for x i tall: hvis x% 2 == 0: print ('% s er et jevnt tall'% (x)) hvis __name__ == '__main__': tall = [43, 50, 5, 98, 34, 35] p1 = Prosess (mål = args = ('x',)) p2 = Prosess (target = is_even, args = ('x',)) p1.start () p2.start () p1.join () p2.join () print "Done" #result 43 squared er 1849 50 squared er 2500 5 squared er 25 98 squared er 9604 34 squared er 1156 35 squared er 1225 50 er et jevnt tall 98 er et jevnt nummer 34 er et jevnt tall Gjort
Multiprosessering støtter to typer kommunikasjonskanaler mellom prosesser:
Kø
Objekter brukes til å overføre data mellom prosesser. De kan lagre alle pickle-able Python objekt, og du kan bruke dem som vist i eksemplet nedenfor:
import multiprosessering def is_even (tall, q): for n i tall: hvis n% 2 == 0: q.put (n) hvis __name__ == "__main__": q = multiprocessing.Queue () p = multiprocessing.Process target = is_even, args = (rekkevidde (20), q)) p.start () p.join () mens q: print (q.get ())
I eksemplet ovenfor lager vi først en funksjon som kontrollerer om et tall er jevnt og deretter legger resultatet i slutten av køen. Vi ordner så et køobjekt og et prosessobjekt og starter prosessen.
Til slutt ser vi om køen er tom, og hvis ikke, får vi verdiene fra forsiden av køen og skriver dem ut til konsollen.
Vi har vist hvordan du deler data mellom to prosesser ved hjelp av en kø, og resultatet er som vist nedenfor.
# resultat 0 2 4 6 8 10 12 14 16 18
Det er også viktig å merke seg at Python har en kømodul som lever i prosessmodulen og brukes til å dele data mellom tråder, i motsetning til multiprocessing-køen som lever i delt minne og brukes til å dele data mellom prosesser.
Rør i multiprosessering brukes primært til kommunikasjon mellom prosesser. Bruk er like enkelt som:
fra multiprocessing import Prosess, Pipe def f (conn): conn.send ([hello world ']) conn.close () hvis __name__ ==' __main__ ': parent_conn, child_conn = Rør () p = Prosess , args = (child_conn,)) p.start () skriv ut parent_conn.recv () p.join ()
Rør()
returnerer to forbindelsesobjekter som representerer rørets to ender. Hvert tilkoblingsobjekt har sende()
og Recv ()
metoder. Her oppretter vi en prosess som skriver ut strengen Hei Verden
og deler deretter dataene over.
# resultat ['hallo verden']
Låser
arbeid ved å sørge for at bare én prosess utføres av gangen, og dermed blokkere andre prosesser fra å utføre lignende kode. Dette gjør det mulig å fullføre prosessen, og først da kan låsen slippes ut.
Eksempelet nedenfor viser en ganske enkel bruk av Lås-metoden.
fra multiprocessing import prosess, lås def hilsen (l, i): l.acquire () skriv ut 'hallo', jeg l.release () hvis __name__ == '__main__': lås = Lås () navn = ['Alex' 'sam', 'Bernard', 'Patrick', 'Jude', 'Williams'] for navn i navn: Prosess (mål = hilsen, args = (lås, navn)). start () #result hei Alex hallo sam hallo Bernard hallo Patrick hallo Jude hallo Williams
I denne koden importerer vi først låsemetoden, anskaffer den, kjører utskriftsfunksjonen, og slipper den deretter.
Multiprocessing-modulen gir også støtte til logging, selv om loggpakken ikke bruker låser, slik at meldinger mellom prosesser kan ende opp med å bli blandet under kjøring.
Bruk av logging er like enkelt som:
import multiprosessering, logging logger = multiprocessing.log_to_stderr () logger.setLevel (logging.INFO) logger.warning ('Feil har oppstått')
Her importerer vi først logging og multiprocessing modulene, og vi definerer deretter multiprocessing.log_to_stderr ()
metode, som utfører et anrop til get_logger ()
samt legge til en handler som sender utdata til sys.stderr
. Endelig setter vi loggernivået og meldingen vi ønsker å formidle.
Denne opplæringen har dekket det som er nødvendig for å komme i gang med multiprocessing i Python. Multiprocessing overvinter problemet med GIL (Global Interpreter Lock) siden den utnytter bruken av delprosesser i stedet for tråder.
Det er mye mer i Python-dokumentasjonen som ikke er dekket i denne opplæringen, så vær så snill å besøke Python multiprocessing docs og benytte den fulle kraften til denne modulen.