Hallo
Ich habe eine Liste von Objekten, die initialisiert werden müssen. Die Initialisierung der einzelnen Objekte kann aufgrund externer Abhängigkeiten relativ lange dauern. Im Moment initialisiere ich die Objekte, indem ich über eine Liste der Objekte iteriere. Da die einzelnen Objekte nicht von einander abängig sind, würde ich diesen Vorgang gerne parallelisieren.
Gibt es eine Möglichkeit, aller OpenMP, For-Loops in Python auf einfache Art und Weise zu parallelisieren? Oder habt ihr vielleicht einen Vorschlag, wie ich dieses Problem eleganter lösen kann?
Vielen Dank für eure Hilfe.
Parallelisierter For-Loop
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Das wird so wie du es dir wünscht vermutlich nicht gehen, denn CPython hat ein globales Lock (GIL), welches verhindert, dass gleichzeitig in mehreren Threads Python-Code ausgeführt wird. Das wird also nur gehen, wenn ein großer Teil deines Codes in C geschrieben ist.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- veers
- User
- Beiträge: 1219
- Registriert: Mittwoch 28. Februar 2007, 20:01
- Wohnort: Zürich (CH)
- Kontaktdaten:
PyProcessing bietet solche Sachen an. Da gibt es zum Beispiel map_async. Eine genaue Antwort wird dir jedoch niemand geben können ohne das Problem genauer zu kennen.
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Danke für eure Antworten.
Die Zeit verstreicht größtenteils beim Warten auf I/O-Anfragen bzw. HTTP und FTP Anfragen. Wird der GIL von den built-in Klassen für HTTP und FTP freigegeben?
Meine Idee war nun, den Vorgang zu beschleunigen, indem die einzelnen "Initialisierungen" mehr oder weniger parallel ausgeführt werden.
Die Anzahl der Objekte ist erst zur Laufzeit bekannt. Es klingt vermutlich viel aufwendiger, als es ist .
Die Zeit verstreicht größtenteils beim Warten auf I/O-Anfragen bzw. HTTP und FTP Anfragen. Wird der GIL von den built-in Klassen für HTTP und FTP freigegeben?
Code: Alles auswählen
objekte = [obj1, obj2, obj3, obj4]
for obj in objekte:
obj.initialisierung() # kann bis zu 10 sekunden dauern, da daten von externen "quellen" geladen werden
# an diesem punkt wären alle objekte initialisiert, allerdings könnte es in diesem beispiel bis zu 40 sekunden dauern
Code: Alles auswählen
objekte = [obj1, obj2, obj3, obj4]
for obj in objekte:
ausführenInNeuemThread(obj.initialisierung()) # kann bis zu 10 sekunden dauern, da daten von externen "quellen" geladen werden
warteBisAlleThreadsBeendetSind()
Du meinst noch einfacher als das hier?
Code: Alles auswählen
import threading
import Queue
#tasks
input_queue = Queue.Queue()
#results
result_queue = Queue.Queue()
class Worker(threading.Thread):
def run(self):
while True:
#get new task
task = input_queue.get()
#process task
result = ...(task)...
result_queue.put(result)
class Consumer(threading.Thread):
def run(self):
while True:
#wait for new result
result = result_queue.get()
#process result
...result...
#fill input queue...
#start consumer
consumer = Consumer()
consumer.start()
#workers
workers = [Worker() for x in range(NUM_WORKERS)]
for worker in workers:
worker.start()
consumer.join()
-
- User
- Beiträge: 1790
- Registriert: Donnerstag 28. Oktober 2004, 16:33
- Wohnort: Graz, Steiermark - Österreich
- Kontaktdaten:
Zuerst der Klassiker: In Erlang ist es einfacher. Jetzt das Problem: In Python hast du das nette GIL und da wird nur ein Kern gleichzeitig arbeiten. Workaround: forken, und da fängt es dann an, dass openmp mehr Spaß macht.EyDu hat geschrieben:Du meinst noch einfacher als das hier?
TUFKAB – the user formerly known as blackbird
Wenn man das alles selber schreibt, und wie sieht's mit Bibliotheken wie Parallel Python (`pp`) oder Pyro aus?
Und im vorliegenden Fall ist der Ansatz von EyDu auch schon wertvoll, da es ja um blockierendes IO geht und dort das GIL freigegeben wird.
Und im vorliegenden Fall ist der Ansatz von EyDu auch schon wertvoll, da es ja um blockierendes IO geht und dort das GIL freigegeben wird.