In Python zijn objecten in het geheugen beschikbaar voor alle threads zonder kopiëren. Echter, bij het werken met processen via multiprocessing worden standaard Python-objecten (zoals lijsten, dictionaries) tussen processen doorgegeven via serialisatie (meestal via pickle), en elke proces krijgt zijn eigen kopie van het object. Wijzigingen in een object in één proces worden niet weerspiegeld in de kopie in een ander proces.
multiprocessing.Manager().dict().# Multiprocessing from multiprocessing import Process, Manager def worker(d): d['a'] = 42 if __name__ == '__main__': # Eenvoudige dict werkt niet tussen processen managed_dict = Manager().dict() p = Process(target=worker, args=(managed_dict,)) p.start(); p.join() print(managed_dict['a']) # 42
In welke gevallen zal het bewerken van een gewone lijst (list) in één proces zichtbaar zijn in een ander proces?
Nooit, als je werkt met multiprocessing. Gewone Python-objecten worden niet gedeeld tussen processen. Voor delen moeten speciale primitive worden gebruikt — Manager-objecten (bijvoorbeeld, Manager().list(), Manager().dict()), die de status tussen processen synchroniseren.
Verhaal
Het team van ontwikkelaars van een web-crawler initialiseerde taakqueues als lijsten en verdeelde deze tussen processen via multiprocessing. Taken “raakten kwijt” omdat processen elkaars updates niet zagen. Dit werd opgelost door gebruik te maken van Manager().list().
Verhaal
In een analytische dienst werden logs geprobeerd te verzamelen in geneste dicts binnen threads. Bij een hoge belasting leidde dit tot race conditions en datacorruptie door een gebrek aan locks.
Verhaal
In een ETL-dienst, bij het proberen om objecten die tijdens de verwerkingsfase zijn verzameld in meerdere processen te verzamelen, ontdekten ze duplicatie/verlies van gegevens: programmeurs hielden geen rekening met het feit dat elk proces met zijn eigen kopie van de structuur werkte en niet met een gezamenlijke.