So che ha detto che l'approccio Pool.map non ha molto senso per voi. La mappa è solo un modo semplice per dargli una fonte di lavoro e un callable da applicare a ciascuno degli elementi. Il func
per la mappa potrebbe essere un qualsiasi punto di ingresso per eseguire il lavoro effettivo sull'arg dato.
Se questo non sembra giusto per te, ho una risposta piuttosto dettagliata qui sull'utilizzo di un modello produttore-consumatore: https://stackoverflow.com/a/11196615/496445
In sostanza, si crea una coda, e iniziare a N numero di lavoratori. Quindi si alimenta la coda dal thread principale o si crea un processo Producer che alimenta la coda. I lavoratori continuano a prendere il lavoro dalla coda e non ci sarà mai più un lavoro simultaneo in atto rispetto al numero di processi che hai avviato.
Hai anche la possibilità di porre un limite alla coda, in modo che blocchi il produttore quando c'è già troppo lavoro in sospeso, se hai bisogno di mettere vincoli anche sulla velocità e sulle risorse che il produttore consuma.
La funzione di lavoro che viene chiamato può fare tutto quello che vuoi. Questo può essere un wrapper attorno ad alcuni comandi di sistema, oppure può importare la tua lib python ed eseguire la routine principale. Esistono sistemi di gestione dei processi specifici che consentono di configurare configurazioni per eseguire i file eseguibili arbitrari con risorse limitate, ma questo è solo un approccio Python di base per farlo.
Frammenti da quella other answer mio:
base 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)
Utilizzando un gestore di processi e produttore
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
Avete provato [pool di processi Python] (http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool)? – C2H5OH
Il modo più semplice per farlo consiste nel creare un programma "controller" che crea il 'multiprocessing.pool' e genera i thread worker (program.py), riallocando il lavoro al termine dell'istanza. – jozzas
Grazie, ci proverò; nel mio primo tentativo, per qualche motivo, sono giunto alla conclusione che multiprocessing.pool non era quello che volevo, ma ora sembra giusto. Quindi in questo caso, i thread di lavoro generano appena program.py (come thread? Con subprocess.Popen)? Potresti per favore pubblicare un esempio approssimativo o implementazione di modelli che potrei seguire? – steadfast