0Pricing
Python Academy · Lekcja

Podstawy multiprocessing

Wykorzystuj wiele rdzeni CPU

Podstawy multiprocessing to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.

Dlaczego multiprocessing?

GIL uniemożliwia wątkom równoległe wykonywanie kodu bajtowego Pythona. Moduł multiprocessing omija to ograniczenie, uruchamiając oddzielne procesy, z których każdy ma własny interpreter i GIL. Dzięki temu zadania obciążające procesor są naprawdę wykonywane na wielu rdzeniach.

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

Uruchamianie procesu

Process(target=func) działa podobnie do interfejsu wątków. Wywołaj start(), aby uruchomić proces, i join(), aby na niego zaczekać.

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

Strażnik __main__

Na niektórych platformach procesy potomne importują skrypt. Bez strażnika if __name__ == '__main__': można przypadkowo uruchamiać procesy rekurencyjnie. Zawsze umieszczaj w nim kod uruchamiający procesy.

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

Przekazywanie argumentów

Użyj args dla argumentów pozycyjnych i kwargs dla argumentów nazwanych, tak jak w przypadku wątków. Argumenty są serializowane za pomocą pickle i przesyłane do procesu potomnego.

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

Pula procesów roboczych

multiprocessing.Pool zarządza grupą procesów. pool.map dzieli obiekt iterowalny między procesy i zbiera wyniki w określonej kolejności.

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

Interfejs concurrent.futures oferuje również ProcessPoolExecutor z takim samym interfejsem submit/map, jaki poznali Państwo w przypadku wątków.

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

Oddzielne przestrzenie pamięci

Każdy proces ma własną pamięć. Zmodyfikowanie zmiennej globalnej w procesie potomnym nie zmienia jej kopii w procesie nadrzędnym. Dane należy jawnie zwrócić lub udostępnić.

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)

Odbieranie wyników

Ponieważ pamięć nie jest współdzielona, należy zwracać wyniki za pomocą Pool.map, executorów lub kolejek, zamiast modyfikować zmienne globalne.

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 dla pojedynczych wywołań

apply_async planuje pojedyncze wywołanie i zwraca uchwyt do wyniku. Wywołaj .get(), aby pobrać wartość.

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

Wymóg serializacji pickle

Obiekty docelowe i argumenty muszą być picklowalne, aby można było przesłać je między procesami. Działają funkcje zdefiniowane na najwyższym poziomie modułu, natomiast funkcje lambda i funkcje lokalne zwykle nie.

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

Kiedy używać procesów

Procesów należy używać do zadań obciążających procesor, takich jak obliczenia matematyczne, przetwarzanie obrazów czy parsowanie. Koszt uruchamiania procesów i serializacji za pomocą pickle sprawia, że lepiej nadają się one do mniejszej liczby cięższych zadań niż do wielu drobnych.

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

Szybki test

Sprawdź, czy rozumie Pan / rozumie Pani podstawy multiprocessing.

Podsumowanie

Poznał Pan / Poznała Pani podstawy multiprocessing:

  • Procesy omijają GIL, umożliwiając rzeczywiste równoległe wykonywanie zadań obciążających procesor.
  • Należy używać strażnika if __name__ == '__main__'.
  • Pool i ProcessPoolExecutor rozdzielają pracę i zbierają wyniki.
  • Pamięć nie jest współdzielona, a argumenty muszą być picklowalne.

Następnie: bezpieczne udostępnianie danych za pomocą kolejek i blokad.

Często zadawane pytania

Czy lekcja „Podstawy multiprocessing” jest bezpłatna?

Tak — pełny tekst „Podstawy multiprocessing” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Podstawy multiprocessing”?

Wykorzystuj wiele rdzeni CPU Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Python Academy?

Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Podstawy multiprocessing”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?

Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wątki i GIL
  2. ThreadPoolExecutor
  3. Podstawy multiprocessing
  4. Bezpieczne współdzielenie danych
← Powrót do Python Academy