W Pythonie przy pracy z wątkami obiekty w pamięci są dostępne dla wszystkich wątków bez kopiowania. Jednak przy pracy z procesami przez multiprocessing standardowe obiekty Pythona (na przykład listy, słowniki) są przekazywane między procesami przez serializację (zwykle przez pickle), a każdy proces otrzymuje swoją kopię obiektu. Zmiana obiektu w jednym procesie nie odbija się na kopii w innym procesie.
multiprocessing.Manager().dict().# Wieloprocesowość from multiprocessing import Process, Manager def worker(d): d['a'] = 42 if __name__ == '__main__': # Zwykły dict nie działa między procesami managed_dict = Manager().dict() p = Process(target=worker, args=(managed_dict,)) p.start(); p.join() print(managed_dict['a']) # 42
Kiedy edytowanie zwykłej listy (list) w jednym procesie odbije się w innym procesie?
Nigdy, jeśli pracujesz z multiprocessing. Zwykłe obiekty Pythona nie są dzielone między procesami. Aby je dzielić, należy używać specjalnych prymitywów — obiektów Manager (na przykład Manager().list(), Manager().dict()), które synchronizują stan między procesami.
Historia
Zespół programistów web crawlera zainicjował kolejki zadań jako listy i dzielił je między procesami przez multiprocessing. Zadania "ginęły", ponieważ procesy nie widziały nawzajem swoich aktualizacji. Naprawiono to na użycie Manager().list().
Historia
W serwisie analitycznym próbowano zbierać logi w zagnieżdżonych dictach wewnątrz wątków. W przypadku scenariuszy o wysokim obciążeniu doprowadziło to do warunków wyścigu i uszkodzenia danych z powodu braku blokad.
Historia
W serwisie ETL podczas próby zebrania zebranych podczas etapu przetwarzania obiektów danych w wielu procesach odkryto duplikację/utrata danych: programiści nie uwzględnili, że każdy proces pracował na swojej kopii struktury, a nie na wspólnej.