Ich weiß, Sie erwähnt, dass die Pool.map Ansatz nicht viel Sinn für Sie macht. Die Karte ist nur eine einfache Möglichkeit, um eine Quelle der Arbeit zu geben, und eine aufrufbar für jeden der Elemente. Die func
für die Karte könnte jeder Einstiegspunkt sein, um die eigentliche Arbeit an dem gegebenen arg zu tun.
Wenn das für Dich scheint nicht richtig, habe ich eine ziemlich detaillierte Antwort hier über ein Producer-Consumer-Muster mit: https://stackoverflow.com/a/11196615/496445
Im Wesentlichen erstellen Sie eine Warteschlange, und starten N Anzahl der Arbeitnehmer. Dann füttern Sie die Warteschlange entweder aus dem Hauptthread oder erstellen einen Producer-Prozess, der die Warteschlange füttert. Die Arbeiter nehmen immer nur Arbeit aus der Warteschlange und es wird niemals mehr gleichzeitige Arbeit geben als die Anzahl der Prozesse, die Sie gestartet haben.
Sie haben auch die Möglichkeit, die Warteschlange zu begrenzen, so dass sie den Erzeuger blockiert, wenn es bereits zu viel ausstehende Arbeit gibt, wenn Sie auch die Geschwindigkeit und Ressourcen des Herstellers einschränken müssen.
Die Arbeitsfunktion, die aufgerufen wird, kann alles tun, was Sie wollen. Dies kann ein Wrapper um einen Systembefehl sein, oder er kann Ihre Python-Lib importieren und die Hauptroutine ausführen. Es gibt bestimmte Prozess-Management-Systeme, die es Ihnen ermöglichen, Konfigurationen für die Ausführung von beliebigen ausführbaren Dateien unter begrenzten Ressourcen einzurichten. Dies ist jedoch nur ein einfacher Python-Ansatz.
Snippets aus diesem other answer von mir:
Grund Pool:
from multiprocessing import Pool
def do_work(val):
# could instantiate some other library class,
# call out to the file system,
# or do something simple right here.
return "FOO: %s" % val
pool = Pool(4)
work = get_work_args()
results = pool.map(do_work, work)
Mit Hilfe eines Prozess-Manager und Produzent
from multiprocessing import Process, Manager
import time
import itertools
def do_work(in_queue, out_list):
while True:
item = in_queue.get()
# exit signal
if item == None:
return
# fake work
time.sleep(.5)
result = item
out_list.append(result)
if __name__ == "__main__":
num_workers = 4
manager = Manager()
results = manager.list()
work = manager.Queue(num_workers)
# start for workers
pool = []
for i in xrange(num_workers):
p = Process(target=do_work, args=(work, results))
p.start()
pool.append(p)
# produce data
# this could also be started in a producer process
# instead of blocking
iters = itertools.chain(get_work_args(), (None,)*num_workers)
for item in iters:
work.put(item)
for p in pool:
p.join()
print results
Haben Sie [Python-Prozesspools] (http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool) ausprobiert? – C2H5OH
Der einfachste Weg, dies zu tun, ist ein "Controller" -Programm zu erstellen, das den 'multiprocessing.pool' erzeugt und die Worker (program.py) -Threads erzeugt, wobei die Arbeit nach Beendigung der Instanzen neu zugewiesen wird. – jozzas
Danke, ich werde es versuchen; Bei meinem ersten Versuch kam ich aus irgendeinem Grund zu dem Schluss, dass multiprocessing.pool nicht das ist, was ich wollte, aber jetzt scheint es richtig zu sein. In diesem Fall würden Worker-Threads einfach program.py erzeugen (als Thread? Mit subprocess.Popen)? Könnten Sie bitte ein ungefähres Beispiel oder eine Template-Implementierung veröffentlichen, der ich folgen könnte? – steadfast