Python Multiprocessing Beispiel
In unserem vorherigen Tutorial haben wir ein Beispiel für Python CSV gelernt. In diesem Tutorial werden wir Python Multiprocessing mit Beispielen lernen.
Python Multiprocessing
Die parallele Verarbeitung erhält heutzutage immer mehr Aufmerksamkeit. Wenn Sie noch nichts über parallele Verarbeitung wissen, lernen Sie von Wikipedia. Da CPU-Hersteller immer mehr Kerne zu ihren Prozessoren hinzufügen, ist das Erstellen von parallelischem Code eine großartige Möglichkeit, die Leistung zu verbessern. Python führte das multiprocessing-Modul ein, um uns zu ermöglichen, parallelen Code zu schreiben. Um die Hauptmotivation dieses Moduls zu verstehen, müssen wir einige Grundlagen über paralleles Programmieren kennen. Nach dem Lesen dieses Artikels hoffen wir, dass Sie in der Lage sein werden, etwas Wissen zu diesem Thema zu sammeln.
Python Multiprocessing Prozess, Warteschlange und Sperren
Es gibt viele Klassen im Python-Multiprocessing-Modul zum Erstellen eines parallelen Programms. Unter ihnen sind die drei grundlegenden Klassen Process, Queue und Lock. Diese Klassen helfen Ihnen, ein paralleles Programm zu erstellen. Bevor wir jedoch darüber sprechen, lassen Sie uns dieses Thema mit einem einfachen Codeeintrag einleiten. Um ein paralleles Programm nützlich zu machen, müssen Sie wissen, wie viele Kerne Ihr PC hat. Das Python-Multiprocessing-Modul ermöglicht es Ihnen, dies herauszufinden. Der folgende einfache Code gibt die Anzahl der Kerne in Ihrem PC aus.
import multiprocessing
print("Number of cpu : ", multiprocessing.cpu_count())
Die folgende Ausgabe kann je nach Ihrem PC variieren. Bei mir beträgt die Anzahl der Kerne 8.
Python Multiprocessing Process-Klasse
Die Process-Klasse in Python multiprocessing ist eine Abstraktion, die einen weiteren Python-Prozess einrichtet, ihm ermöglicht, Code auszuführen, und der übergeordneten Anwendung eine Möglichkeit bietet, die Ausführung zu steuern. Es gibt zwei wichtige Funktionen, die zur Process-Klasse gehören - die start()- und die join()-Funktion. Zuerst müssen wir eine Funktion schreiben, die vom Prozess ausgeführt wird. Dann müssen wir ein Prozessobjekt instanziieren. Wenn wir ein Prozessobjekt erstellen, passiert nichts, bis wir ihm über die start()-Funktion mitteilen, mit der Verarbeitung zu beginnen. Dann wird der Prozess ausgeführt und gibt sein Ergebnis zurück. Nachdem wir den Prozess über die join()-Funktion zum Abschluss bringen, bleibt der Prozess ohne den Aufruf der join()-Funktion untätig und wird nicht beendet. Wenn Sie also viele Prozesse erstellen und diese nicht beenden, können Sie mit Ressourcenmangel konfrontiert werden. Dann müssen Sie sie möglicherweise manuell beenden. Eine wichtige Sache ist, dass Sie, wenn Sie ein Argument über den Prozess übergeben möchten, das Schlüsselwortargument args verwenden müssen. Der folgende Code wird hilfreich sein, um die Verwendung der Process-Klasse zu verstehen.
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()
# instantiating process with arguments
for name in names:
# print(name)
proc = Process(target=print_func, args=(name,))
procs.append(proc)
proc.start()
# complete the processes
for proc in procs:
proc.join()
Die Ausgabe des folgenden Codes wird sein:
Python Multiprocessing Warteschlangenklasse
Sie haben grundlegende Kenntnisse über computerbezogene Datenstrukturen, wahrscheinlich wissen Sie über Warteschlangen Bescheid. Das Python Multiprocessing-Modul bietet die Klasse Queue, die genau eine First-In-First-Out Datenstruktur ist. Sie können beliebige pickled Python-Objekte speichern (obwohl einfache am besten sind) und sind äußerst nützlich für die gemeinsame Nutzung von Daten zwischen Prozessen. Warteschlangen sind besonders nützlich, wenn sie als Parameter an die Ziel-Funktion eines Prozesses übergeben werden, um dem Prozess zu ermöglichen, Daten zu konsumieren. Mit der Funktion put() können wir Daten in die Warteschlange einfügen und mit get() können wir Elemente aus Warteschlangen abrufen. Siehe den folgenden Code für ein schnelles Beispiel.
from multiprocessing import Queue
colors = ['red', 'green', 'blue', 'black']
cnt = 1
instantiating a queue object
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 Lock-Klasse
Die Aufgabe der Lock-Klasse ist ganz einfach. Sie ermöglicht es dem Code, einen Lock zu beanspruchen, sodass kein anderer Prozess denselben Code ausführen kann, bis der Lock freigegeben wurde. Die Aufgabe der Lock-Klasse besteht hauptsächlich aus zwei Teilen. Der eine ist, den Lock zu beanspruchen, und der andere ist, den Lock freizugeben. Um den Lock zu beanspruchen, wird die Funktion acquire() verwendet, und um den Lock freizugeben, wird die Funktion release() verwendet.
Beispiel für Python-Multiprocessing
In diesem Beispiel zur Multiprocessing in Python werden wir unser gesamtes Wissen zusammenführen. Angenommen, wir haben einige Aufgaben zu erledigen. Um diese Aufgabe zu erledigen, werden wir mehrere Prozesse verwenden. Daher werden wir zwei Warteschlangen beibehalten. Eine wird die Aufgaben enthalten, und die andere wird das Protokoll der abgeschlossenen Aufgaben enthalten. Dann instanziieren wir die Prozesse, um die Aufgabe zu erledigen. Beachten Sie, dass die Python-Queue-Klasse bereits synchronisiert ist. Das bedeutet, dass wir die Lock-Klasse nicht verwenden müssen, um mehrere Prozesse daran zu hindern, auf dasselbe Warteschlangenobjekt zuzugreifen. Deshalb müssen wir in diesem Fall keine Lock-Klasse verwenden. Unten ist die Implementierung, bei der wir Aufgaben zur Warteschlange hinzufügen, dann Prozesse erstellen und starten und schließlich join() verwenden, um die Prozesse abzuschließen. Schließlich drucken wir das Protokoll aus der zweiten Warteschlange aus.
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))
# creating processes
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()
# completing process
for p in processes:
p.join()
# print the output
while not tasks_that_are_done.empty():
print(tasks_that_are_done.get())
return True
if __name__ == '__main__':
main()
Je nach Anzahl der Aufgaben wird der Code einige Zeit benötigen, um Ihnen die Ausgabe anzuzeigen. Die Ausgabe des folgenden Codes kann von Zeit zu Zeit variieren.
Python Multiprocessing Pool
Der Python-Multiprocessing-Pool kann zur parallelen Ausführung einer Funktion über mehrere Eingabewerte hinweg verwendet werden, indem die Eingabedaten auf die Prozesse verteilt werden (Datenparallelismus). Unten ist ein einfaches Beispiel für den Python-Multiprocessing-Pool.
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()
Das untenstehende Bild zeigt die Ausgabe des obigen Programms. Beachten Sie, dass die Poolgröße 2 beträgt, sodass zwei Ausführungen der work_log-Funktion parallel ablaufen. Wenn eine der verarbeitenden Funktionen fertig ist, wird das nächste Argument übernommen und so weiter.





