Il pacchetto multiprocessing supporta i processi di spawning utilizzando un'API simile al modulo di threading. Offre anche concorrenza locale e remota. Questo tutorial discuterà la multiprocessing in Python e come usare il multiprocessing per comunicare tra i processi ed eseguire la sincronizzazione tra i processi, così come la registrazione.
Il multiprocessing funziona creando un Processi
oggetto e poi chiamandolo inizio()
metodo come mostrato di seguito.
dal processo di importazione multiprocessing Processo def greeting (): stampa 'hello world' se __name__ == '__main__': p = Process (target = greeting) p.start () p.join ()
Nel codice di esempio sopra, prima importiamo la classe Process e quindi istanziamo l'oggetto Process con la funzione di saluto che vogliamo eseguire.
Quindi diciamo al processo di iniziare a usare il inizio()
metodo, e finalmente completiamo il processo con aderire()
metodo.
Inoltre, è possibile anche passare argomenti alla funzione fornendo il args
argomento di parole chiave come questo:
dal processo di multiprocessing Processo di saluto def (nome): stampa 'hello' + "" + nome se __name__ == '__main__': p = Processo (target = greeting, args = ('world',)) p.start () p .aderire()
Diamo un'occhiata ad un esempio più dettagliato che copre tutti i concetti che abbiamo discusso sopra.
In questo esempio, creeremo un processo che calcola il quadrato di numeri e stampa i risultati sulla console.
da multiprocessing import Processo def square (x): per x nei numeri: print ('% s quadrato è% s'% (x, x ** 2)) se __name__ == '__main__': numeri = [43, 50, 5, 98, 34, 35] p = Processo (target = square, args = ('x',)) p.start () p.invio stampa "Fatto" #risultato Fatto 43 al quadrato è 1849 50 al quadrato è 2500 5 al quadrato è 25 98 al quadrato è 9604 34 al quadrato è 1156 35 al quadrato è 1225
Puoi anche creare più di un processo contemporaneamente, come mostrato nell'esempio seguente, in cui il processo p1 ottiene i risultati dei numeri al quadrato, mentre il secondo processo p2 verifica se i numeri indicati sono pari.
da multiprocessing import Processo def square (x): per x nei numeri: print ('% s quadrato è% s'% (x, x ** 2)) def is_even (x): per x nei numeri: se x% 2 == 0: print ('% s è un numero pari'% (x)) se __name__ == '__main__': numeri = [43, 50, 5, 98, 34, 35] p1 = Processo (target = quadrato, args = ('x',)) p2 = Processo (target = is_even, args = ('x',)) p1.start () p2.start () p1.join () p2.join () stampa "Fatto" #result 43 squared è 1849 50 squared è 2500 5 squared è 25 98 squared è 9604 34 squared è 1156 35 squared è 1225 50 è un numero pari 98 è un numero pari 34 è un numero pari Fatto
Il multiprocessing supporta due tipi di canali di comunicazione tra i processi:
Coda
gli oggetti sono usati per passare i dati tra i processi. Possono memorizzare qualsiasi oggetto Python in grado di decollare e possono essere utilizzati come mostrato nell'esempio seguente:
import multiprocessing def is_even (numbers, q): per n in numeri: if n% 2 == 0: q.put (n) if __name__ == "__main__": q = multiprocessing.Queue () p = multiprocessing.Process ( target = is_even, args = (range (20), q)) p.start () p.join () while q: print (q.get ())
Nell'esempio sopra, prima creiamo una funzione che controlla se un numero è pari e quindi inserisce il risultato alla fine della coda. Quindi istanziamo un oggetto coda e un oggetto processo e iniziamo il processo.
Infine, controlliamo se la coda è vuota, e in caso contrario, otteniamo i valori dalla parte anteriore della coda e li stampiamo sulla console.
Abbiamo mostrato come condividere i dati tra due processi usando una coda, e il risultato è come mostrato di seguito.
# result 0 2 4 6 8 10 12 14 16 18
È anche importante notare che Python ha un modulo Queue che vive nel modulo del processo e viene utilizzato per condividere i dati tra i thread, diversamente dalla coda di multiprocessing che vive nella memoria condivisa e viene utilizzata per condividere i dati tra i processi.
I tubi in multiprocessing vengono principalmente utilizzati per la comunicazione tra processi. L'utilizzo è semplice come:
dal processo di importazione multiprocessing, Pipe def f (conn): conn.send (['hello world']) conn.close () se __name__ == '__main__': parent_conn, child_conn = Pipe () p = Process (target = f , args = (child_conn,)) p.start () stampa parent_conn.recv () p.join ()
Tubo()
restituisce due oggetti di connessione che rappresentano le due estremità della pipe. Ogni oggetto di connessione ha inviare()
e recv ()
metodi. Qui creiamo un processo che stampa la stringa Ciao mondo
e quindi condivide i dati.
# result ["Ciao mondo"]
serrature
lavorare assicurandosi che venga eseguito un solo processo alla volta, impedendo quindi ad altri processi di eseguire codice simile. Ciò consente di completare il processo e solo allora il blocco può essere rilasciato.
L'esempio seguente mostra un uso piuttosto semplice del metodo Lock.
dal processo di importazione multiprocessing, Lock def greeting (l, i): l.acquire () stampa 'hello', i l.release () if __name__ == '__main__': lock = Lock () names = ['Alex', 'sam', 'Bernard', 'Patrick', 'Jude', 'Williams'] per nome nei nomi: Process (target = greeting, args = (lock, name)). start () #result ciao Alex ciao sam ciao Bernard ciao Patrick ciao Jude ciao Williams
In questo codice, prima importiamo il metodo Lock, lo acquisiamo, eseguiamo la funzione di stampa e quindi lo rilasciamo.
Il modulo multiprocessing fornisce anche il supporto per la registrazione, sebbene il pacchetto di registrazione non utilizzi i blocchi in modo che i messaggi tra i processi possano finire per essere confusi durante l'esecuzione.
L'utilizzo della registrazione è semplice come:
import multiprocessing, logging logger = multiprocessing.log_to_stderr () logger.setLevel (logging.INFO) logger.warning ('Errore si è verificato')
Qui prima importiamo i moduli di logging e multiprocessing e quindi definiamo il file multiprocessing.log_to_stderr ()
metodo, che esegue una chiamata a get_logger ()
oltre ad aggiungere un gestore che invia l'output a sys.stderr
. Infine, impostiamo il livello del logger e il messaggio che vogliamo trasmettere.
Questo tutorial ha coperto ciò che è necessario per iniziare con il multiprocessing in Python. Il multiprocessing risolve il problema di GIL (Global Interpreter Lock) poiché sfrutta l'utilizzo di sottoprocessi anziché thread.
C'è molto altro nella documentazione di Python che non è trattata in questo tutorial, quindi sentiti libero di visitare i documenti di multiprocessing di Python e sfrutta tutta la potenza di questo modulo.