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.) Pool
També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.map
para 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 ProcessPoolExecutor
também possui duas linhas ( .map
retorna um gerador, portanto você precisa do list()
):
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor() as executor:
print(list(executor.map(worker, range(10))))
Com Process
es 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 SimpleQueue
se tudo que você precisa é put
e get
. O primeiro loop inicia todos os processos, antes que o segundo faça as queue.get
chamadas de bloqueio . Acho que também não há motivo para ligar p.join()
.
multiprocessing.Queue
, em vez de umManager
aqui. Usar umManager
requer gerar um processo totalmente novo, que é um exagero quando umQueue
faria.