"I processi figlio generati tramite multiprocessing condividono oggetti creati in precedenza nel programma?"
No (python prima della 3.8) e Sì nella 3.8 ( https://docs.python.org/3/library/multiprocessing.shared_memory.html#module-multiprocessing.shared_memory )
I processi hanno uno spazio di memoria indipendente.
Soluzione 1
Per utilizzare al meglio una grande struttura con molti lavoratori, fallo.
Scrivi ogni worker come un "filtro": legge i risultati intermedi da stdin, funziona, scrive i risultati intermedi su stdout.
Connetti tutti i lavoratori come una pipeline:
process1 <source | process2 | process3 | ... | processn >result
Ogni processo legge, funziona e scrive.
Ciò è notevolmente efficiente poiché tutti i processi vengono eseguiti contemporaneamente. Le scritture e le letture passano direttamente attraverso i buffer condivisi tra i processi.
Soluzione 2
In alcuni casi, hai una struttura più complessa, spesso una struttura "fan-out". In questo caso hai un genitore con più figli.
Il genitore apre i dati di origine. Il genitore biforca un certo numero di bambini.
Il genitore legge la sorgente, coltiva parti della sorgente a ogni figlio in esecuzione contemporaneamente.
Quando il genitore raggiunge la fine, chiudi il tubo. Il bambino ottiene la fine del file e finisce normalmente.
Le parti del bambino sono piacevoli da scrivere perché ogni bambino legge semplicemente sys.stdin
.
Il genitore ha un po 'di fantasia nel generare tutti i bambini e nel mantenere i tubi correttamente, ma non è poi così male.
Fan-in è la struttura opposta. Un certo numero di processi in esecuzione in modo indipendente devono intercalare i propri input in un processo comune. Il raccoglitore non è così facile da scrivere, poiché deve leggere da molte fonti.
La lettura da molte pipe con nome viene spesso eseguita utilizzando il select
modulo per vedere quali pipe hanno input in sospeso.
Soluzione 3
La ricerca condivisa è la definizione di un database.
Soluzione 3A: carica un database. Consenti ai lavoratori di elaborare i dati nel database.
Soluzione 3B: creare un server molto semplice utilizzando werkzeug (o simile) per fornire applicazioni WSGI che rispondono a HTTP GET in modo che i lavoratori possano interrogare il server.
Soluzione 4
Oggetto filesystem condiviso. Il sistema operativo Unix offre oggetti di memoria condivisa. Questi sono solo file che vengono mappati alla memoria in modo che lo scambio di I / O venga eseguito invece di più letture memorizzate nel buffer della convenzione.
Puoi farlo da un contesto Python in diversi modi
Scrivi un programma di avvio che (1) spezzi il tuo oggetto gigantesco originale in oggetti più piccoli e (2) inizi i worker, ciascuno con un oggetto più piccolo. Gli oggetti più piccoli potrebbero essere oggetti Python decapati per risparmiare un po 'di tempo di lettura del file.
Scrivete un programma di avvio che (1) legga il vostro gigantesco oggetto originale e scriva un file strutturato in pagine e codificato in byte utilizzando seek
operazioni per garantire che le singole sezioni siano facili da trovare con semplici ricerche. Questo è ciò che fa un motore di database: suddividere i dati in pagine, rendere ogni pagina facile da individuare tramite un file seek
.
Genera lavoratori con accesso a questo file di grandi dimensioni strutturato a pagina. Ogni lavoratore può cercare le parti pertinenti e svolgere il proprio lavoro lì.
marshal.load
genitore e ogni figlio (ogni processo importa il modulo).