Nel nostro tutorial precedente, abbiamo appreso l’Esempio di CSV Python. In questo tutorial, impareremo il Multiprocessing in Python con degli esempi.
Multiprocessing in Python
Il processing parallelo sta ottenendo sempre più attenzione oggi. Se ancora non conosci il concetto di processing parallelo, impara da wikipedia. Poiché i produttori di CPU continuano ad aggiungere sempre più core ai loro processori, creare codice parallelo è un ottimo modo per migliorare le prestazioni. Python ha introdotto il modulo multiprocessing per consentirci di scrivere codice parallelo. Per capire la principale motivazione di questo modulo, dobbiamo conoscere alcuni concetti di base sulla programmazione parallela. Dopo aver letto questo articolo, speriamo che tu possa acquisire una certa conoscenza su questo argomento.
Processo Python Multiprocessing, Coda e Lock
Ci sono molte classi nel modulo di multiprocessing di Python per la costruzione di un programma parallelo. Tra queste, tre classi di base sono Process
, Queue
e Lock
. Queste classi ti aiuteranno a costruire un programma parallelo. Ma prima di descriverle, iniziamo questo argomento con un codice semplice. Per rendere utile un programma parallelo, devi sapere quanti core ci sono nel tuo pc. Il modulo Multiprocessing di Python ti permette di saperlo. Il seguente codice semplice stamperà il numero di core nel tuo pc.
import multiprocessing
print("Number of cpu : ", multiprocessing.cpu_count())
La seguente output potrebbe variare per il tuo pc. Per me, il numero di core è 8.
Classe Process del modulo multiprocessing di Python
La classe Process
di multiprocessing di Python è un’astrazione che configura un altro processo Python, gli fornisce del codice da eseguire e un modo per il genitore dell’applicazione di controllare l’esecuzione. Ci sono due funzioni importanti che appartengono alla classe Process – la funzione start()
e la funzione join()
. Innanzitutto, dobbiamo scrivere una funzione che verrà eseguita dal processo. Poi, dobbiamo istanziare un oggetto processo. Se creiamo un oggetto processo, nulla accadrà fino a quando non gli diremo di iniziare l’elaborazione tramite la funzione start()
. Quindi, il processo verrà eseguito e restituirà il suo risultato. Dopo di ciò, diciamo al processo di completare tramite la funzione join()
. Senza la chiamata alla funzione join()
, il processo rimarrà inattivo e non terminerà. Quindi, se crei molti processi e non li termini, potresti affrontare la scarsità di risorse. In seguito potresti aver bisogno di terminarli manualmente. Una cosa importante è che, se vuoi passare un qualsiasi argomento attraverso il processo, devi utilizzare l’argomento di parola chiave args
. Il seguente codice sarà utile per comprendere l’uso della classe Process.
from multiprocessing import Process
def print_func(continent='Asia'):
print('The name of continent is : ', continent)
if __name__ == "__main__": # confirms that the code is under main function
names = ['America', 'Europe', 'Africa']
procs = []
proc = Process(target=print_func) # instantiating without any argument
procs.append(proc)
proc.start()
# istanziazione del processo con argomenti
for name in names:
# print(name)
proc = Process(target=print_func, args=(name,))
procs.append(proc)
proc.start()
# completare i processi
for proc in procs:
proc.join()
L’output del seguente codice sarà:
Classe Queue di multiprocessing di Python
Il modulo Python Multiprocessing fornisce la classe Queue
che è esattamente una struttura dati First-In-First-Out. Possono memorizzare qualsiasi oggetto Python picklable (anche se quelli semplici sono i migliori) e sono estremamente utili per condividere dati tra processi. Le code sono particolarmente utili quando vengono passate come parametro alla funzione target di un Process per consentire al Process di consumare dati. Utilizzando la funzione put()
possiamo inserire dati nella coda e utilizzando get()
possiamo ottenere elementi dalle code. Vedere il seguente codice per un esempio rapido.
from multiprocessing import Queue
colors = ['red', 'green', 'blue', 'black']
cnt = 1
# istanziare un oggetto coda
queue = Queue()
print('pushing items to queue:')
for color in colors:
print('item no: ', cnt, ' ', color)
queue.put(color)
cnt += 1
print('\npopping items from queue:')
cnt = 0
while not queue.empty():
print('item no: ', cnt, ' ', queue.get())
cnt += 1
Python multiprocessing Classe Lock
Il compito della classe Lock è piuttosto semplice. Consente al codice di reclamare un blocco in modo che nessun altro processo possa eseguire il codice simile fino a quando il blocco non è stato rilasciato. Quindi il compito della classe Lock è principalmente due. Uno è reclamare il blocco e l’altro è rilasciare il blocco. Per reclamare il blocco, viene utilizzata la funzione acquire()
e per rilasciare il blocco viene utilizzata la funzione release()
.
Esempio di multiprocessing in Python
In questo esempio di multiprocessing Python, uniremo tutte le nostre conoscenze insieme. Supponiamo di avere alcune attività da completare. Per completare quella attività, utilizzeremo diversi processi. Quindi, manterremo due code. Una conterrà le attività e l’altra conterrà il registro delle attività completate. Quindi istanziamo i processi per completare l’attività. Nota che la classe Queue di Python è già sincronizzata. Ciò significa che non è necessario utilizzare la classe Lock per bloccare l’accesso a più processi allo stesso oggetto di coda. Ecco perché, in questo caso, non è necessario utilizzare la classe Lock. Di seguito è riportata l’implementazione in cui stiamo aggiungendo attività alla coda, quindi creando processi e avviandoli, quindi utilizzando join()
per completare i processi. Infine, stampiamo il registro dalla seconda coda.
from multiprocessing import Lock, Process, Queue, current_process
import time
import queue # imported for using queue.Empty exception
def do_job(tasks_to_accomplish, tasks_that_are_done):
while True:
try:
'''
try to get task from the queue. get_nowait() function will
raise queue.Empty exception if the queue is empty.
queue(False) function would do the same task also.
'''
task = tasks_to_accomplish.get_nowait()
except queue.Empty:
break
else:
'''
if no exception has been raised, add the task completion
message to task_that_are_done queue
'''
print(task)
tasks_that_are_done.put(task + ' is done by ' + current_process().name)
time.sleep(.5)
return True
def main():
number_of_task = 10
number_of_processes = 4
tasks_to_accomplish = Queue()
tasks_that_are_done = Queue()
processes = []
for i in range(number_of_task):
tasks_to_accomplish.put("Task no " + str(i))
# creazione dei processi
for w in range(number_of_processes):
p = Process(target=do_job, args=(tasks_to_accomplish, tasks_that_are_done))
processes.append(p)
p.start()
# completamento del processo
for p in processes:
p.join()
# stampa dell'output
while not tasks_that_are_done.empty():
print(tasks_that_are_done.get())
return True
if __name__ == '__main__':
main()
A seconda del numero di attività, il codice impiegherà del tempo per mostrare l’output. L’output del seguente codice varierà di volta in volta.
Piscina di multiprocessing Python
La piscina di multiprocessing Python può essere utilizzata per l’esecuzione parallela di una funzione su più valori di input, distribuendo i dati di input tra i processi (parallelismo dei dati). Di seguito è riportato un semplice esempio di piscina di multiprocessing Python.
from multiprocessing import Pool
import time
work = (["A", 5], ["B", 2], ["C", 1], ["D", 3])
def work_log(work_data):
print(" Process %s waiting %s seconds" % (work_data[0], work_data[1]))
time.sleep(int(work_data[1]))
print(" Process %s Finished." % work_data[0])
def pool_handler():
p = Pool(2)
p.map(work_log, work)
if __name__ == '__main__':
pool_handler()
Di seguito viene mostrato l’output del programma sopra. Notare che la dimensione della pool è 2, quindi due esecuzioni della funzione work_log
avvengono in parallelo. Quando una delle funzioni ha finito il processo, prende l’argomento successivo e così via. Ecco tutto per il modulo di multiprocessing di Python. Riferimento: Documentazione ufficiale
Source:
https://www.digitalocean.com/community/tutorials/python-multiprocessing-example