Python Academy · Lektion

Grundlæggende om multiprocessing

Brug flere CPU-kerner

Lektion 3 af 413 trin

Grundlæggende om multiprocessing er en gratis Python Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Python Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Python Academy-kurset indeholder 4 lektioner i alt.

Hvorfor multiprocessing?

GIL forhindrer tråde i at køre Python-bytecode parallelt. Modulet multiprocessing omgår dette ved at starte separate processer, hver med sin egen fortolker og GIL, så CPU-bundet arbejde faktisk kører på flere kerner.

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

Start af en proces

Process(target=func) afspejler threading-API'et. Kald start() for at starte processen og join() for at vente.

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

Beskyttelsen af __main__

På nogle platforme importerer underprocesser dit script. Uden en beskyttelse med if __name__ == '__main__': kan du starte processer rekursivt. Pak altid startkoden ind 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()

Overførsel af argumenter

Brug args til positionsargumenter og kwargs til nøgleordsargumenter, ligesom med tråde. Argumenterne serialiseres med pickle og sendes til underprocessen.

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

En pulje af arbejdere

multiprocessing.Pool håndterer en gruppe processer. pool.map fordeler en iterabel mellem dem og samler resultaterne i rækkefø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 tilbyder også ProcessPoolExecutor med den samme submit/map-grænseflade, som du så for tråde.

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 hukommelsesområder

Hver proces har sin egen hukommelse. Hvis du ændrer en global variabel i en underproces, ændrer det ikke forælderprocessens kopi. Data skal returneres eller deles eksplicit.

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)

Hentning af resultater

Da hukommelsen ikke deles, skal du returnere resultater gennem Pool.map, executor-objekter eller køer i stedet for at ændre 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 til enkeltkald

apply_async planlægger ét kald og returnerer et resultathåndtag. Kald .get() for at hente værdien.

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 skal kunne serialiseres med pickle, så de kan krydse procesgrænsen. Funktioner på øverste niveau fungerer; lambdaer og lokale funktioner gør det normalt 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]))

Hvornår skal du vælge processer?

Brug processer til CPU-bundet arbejde som matematik, billedbehandling og fortolkning. Omkostningerne ved at starte processer og serialisere med pickle betyder, at de egner sig til færre, tungere opgaver frem for mange små.

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

Hurtigtjek

Afprøv din forståelse af multiprocessing.

Opsummering

Du har lært det grundlæggende i multiprocessing:

  • Processer omgår GIL og giver ægte CPU-parallelitet.
  • Brug beskyttelsen med if __name__ == '__main__'.
  • Pool og ProcessPoolExecutor fordeler arbejdet og samler resultaterne.
  • Hukommelsen deles ikke, og argumenter skal kunne serialiseres med pickle.

Næste emne: sikker deling af data med køer og låse.

Gratis at komme i gang

Lær Python med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
76
Lektioner
320

Ofte stillede spørgsmål

Er lektionen “Grundlæggende om multiprocessing” gratis?

Ja — hele teksten til “Grundlæggende om multiprocessing” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Python Academy-kurset, skal du opgradere til CoddyKit PRO. Python Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Grundlæggende om multiprocessing”?

Brug flere CPU-kerner Du øver dig i Python Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Python Academy?

Der kræves ingen tidligere erfaring. Python Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Grundlæggende om multiprocessing”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Python Academy-lektion?

Ja. Alle Python Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Tråde og GIL
  2. ThreadPoolExecutor
  3. Grundlæggende om multiprocessing
  4. Sikker deling af data
← Tilbage til Python Academy