Python Academy · leksjon

Grunnleggende om multiprocessing

Bruk flere CPU-kjerner

Leksjon 3 av 413 trinn

Grunnleggende om multiprocessing er en gratis leksjon i Python Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Python Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hvorfor multiprocessing?

GIL hindrer tråder i å kjøre Python-bytekode parallelt. Modulen multiprocessing omgår dette ved å starte separate prosesser, der hver prosess har sin egen tolk og GIL. Dermed kjører CPU-bundet arbeid virkelig på flere kjerner.

import multiprocessing as mp
print('CPU cores available:', mp.cpu_count())

Starte en prosess

Process(target=func) følger samme API som tråder. Kall start() for å starte prosessen og join() for å vente på den.

import multiprocessing as mp

def worker():
    print('hello from a child process')

if __name__ == '__main__':
    p = mp.Process(target=worker)
    p.start()
    p.join()
    print('parent done')

__main__-beskyttelsen

På noen plattformer importerer underprosesser skriptet ditt. Uten en if __name__ == '__main__':-beskyttelse kan du starte prosesser rekursivt. Pakk alltid oppstartskoden inn i den.

import multiprocessing as mp

def task(n):
    print('processing', n)

if __name__ == '__main__':
    for i in range(3):
        p = mp.Process(target=task, args=(i,))
        p.start()
        p.join()

Sende argumenter

Bruk args for posisjonsargumenter og kwargs for nøkkelordargumenter, akkurat som med tråder. Argumentene serialiseres med pickle og sendes til underprosessen.

import multiprocessing as mp

def show(label, times):
    for _ in range(times):
        print(label)

if __name__ == '__main__':
    p = mp.Process(target=show, args=('hi',), kwargs={'times': 2})
    p.start()
    p.join()

Et basseng med arbeidere

multiprocessing.Pool administrerer en gruppe prosesser. pool.map fordeler en itererbar sekvens mellom dem og samler resultatene i riktig rekkefølge.

import multiprocessing as mp

def square(n):
    return n * n

if __name__ == '__main__':
    with mp.Pool(processes=2) as pool:
        print(pool.map(square, range(6)))

ProcessPoolExecutor

API-et concurrent.futures tilbyr også ProcessPoolExecutor, med det samme submit/map-grensesnittet som du så for tråder.

from concurrent.futures import ProcessPoolExecutor

def cube(n):
    return n ** 3

if __name__ == '__main__':
    with ProcessPoolExecutor() as ex:
        print(list(ex.map(cube, range(5))))

Separate minneområder

Hver prosess har sitt eget minne. Hvis du endrer en global variabel i en underprosess, endres ikke forelderprosessens kopi. Data må returneres eller deles eksplisitt.

import multiprocessing as mp

counter = 0

def bump():
    global counter
    counter += 100

if __name__ == '__main__':
    p = mp.Process(target=bump)
    p.start()
    p.join()
    print('parent counter still:', counter)

Hente resultater tilbake

Fordi minnet ikke deles, bør du returnere resultater gjennom Pool.map, executor-er eller køer i stedet for å endre globale variabler.

import multiprocessing as mp

def double(n):
    return n * 2

if __name__ == '__main__':
    with mp.Pool(2) as pool:
        results = pool.map(double, [1, 2, 3, 4])
    print('results:', results)

apply_async for enkeltkall

apply_async planlegger ett kall og returnerer et resultatobjekt. Kall .get() for å hente verdien.

import multiprocessing as mp

def add(a, b):
    return a + b

if __name__ == '__main__':
    with mp.Pool(2) as pool:
        r = pool.apply_async(add, (3, 4))
        print(r.get())

Krav om pickle-serialisering

Mål og argumenter må være picklebare slik at de kan krysse prosessgrensen. Funksjoner på toppnivå fungerer; lambda-funksjoner og lokale funksjoner gjør det vanligvis ikke.

import multiprocessing as mp

def top_level(n):
    return n + 1

if __name__ == '__main__':
    with mp.Pool(2) as pool:
        print(pool.map(top_level, [10, 20]))

Når du bør bruke prosesser

Bruk prosesser til CPU-bundet arbeid, for eksempel matematikk, bildebehandling og parsing. Kostnadene ved å starte prosesser og pickle data gjør dem bedre egnet for færre og tyngre oppgaver enn for mange små oppgaver.

import multiprocessing as mp

def heavy(n):
    return sum(i * i for i in range(n))

if __name__ == '__main__':
    with mp.Pool() as pool:
        print(pool.map(heavy, [1000, 2000, 3000]))

Kort test

Test forståelsen din av multiprocessing.

Oppsummering

Du har lært det grunnleggende om multiprocessing:

  • Prosesser omgår GIL og gir ekte parallell kjøring av CPU-bundet arbeid.
  • Bruk if __name__ == '__main__'-beskyttelsen.
  • Pool og ProcessPoolExecutor fordeler arbeid og samler resultater.
  • Minne deles ikke; argumenter må kunne serialiseres med pickle.

Neste: trygg deling av data med køer og låser.

Gratis å komme i gang

Lær deg Python med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
76
Leksjoner
320

Ofte stilte spørsmål

Er leksjonen «Grunnleggende om multiprocessing» gratis?

Ja – hele teksten i «Grunnleggende om multiprocessing» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Python Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Python Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Grunnleggende om multiprocessing»?

Bruk flere CPU-kjerner Du øver på Python Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Python Academy?

Ingen tidligere erfaring er nødvendig. Python Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Grunnleggende om multiprocessing»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Python Academy-leksjonen?

Ja. Alle Python Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Tråder og GIL
  2. ThreadPoolExecutor
  3. Grunnleggende om multiprocessing
  4. Trygg deling av data
← Tilbake til Python Academy