Pensei em simplificar os exemplos mais simples copiados de cima, trabalhando para mim no Py3.6. O mais simples é multiprocessing.Pool:
import multiprocessing
import time
def worker(x):
time.sleep(1)
return x
pool = multiprocessing.Pool()
print(pool.map(worker, range(10)))
Você pode definir o número de processos no pool com, por exemplo Pool(processes=5),. No entanto, o padrão é a contagem de CPU, portanto, deixe em branco para tarefas associadas à CPU. (As tarefas vinculadas à E / S geralmente se adequam aos threads de qualquer maneira, pois os threads estão aguardando a maior parte do tempo para compartilhar um núcleo da CPU.) PoolTambém se aplica à otimização de chunking .
(Observe que o método worker não pode ser aninhado em um método. Inicialmente, defini meu método worker dentro do método que faz a chamada pool.mappara manter tudo independente, mas os processos não puderam importá-lo e joguei "AttributeError : Não é possível selecionar o objeto local outer_method..inner_method ". Mais aqui . Ele pode estar dentro de uma classe.)
(Aprecie a pergunta original especificada e 'represent!'não a impressão time.sleep(), mas sem ela achei que algum código estava sendo executado simultaneamente quando não estava.)
O Py3 ProcessPoolExecutortambém possui duas linhas ( .mapretorna um gerador, portanto você precisa do list()):
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor() as executor:
print(list(executor.map(worker, range(10))))
Com Processes simples :
import multiprocessing
import time
def worker(x, queue):
time.sleep(1)
queue.put(x)
queue = multiprocessing.SimpleQueue()
tasks = range(10)
for task in tasks:
multiprocessing.Process(target=worker, args=(task, queue,)).start()
for _ in tasks:
print(queue.get())
Use SimpleQueuese tudo que você precisa é pute get. O primeiro loop inicia todos os processos, antes que o segundo faça as queue.getchamadas de bloqueio . Acho que também não há motivo para ligar p.join().
multiprocessing.Queue, em vez de umManageraqui. Usar umManagerrequer gerar um processo totalmente novo, que é um exagero quando umQueuefaria.