Existe uma classe Pool para threads de trabalho , semelhante à classe Pool do módulo de multiprocessamento ?
Eu gosto, por exemplo, da maneira fácil de paralelizar uma função de mapa
def long_running_func(p):
c_func_no_gil(p)
p = multiprocessing.Pool(4)
xs = p.map(long_running_func, range(100))
no entanto, eu gostaria de fazê-lo sem a sobrecarga de criar novos processos.
Eu sei sobre o GIL. No entanto, no meu caso de usuário, a função será uma função C vinculada a IO para a qual o wrapper python liberará o GIL antes da chamada de função real.
Eu tenho que escrever minha própria piscina de threading?
from multiprocessing.pool import ThreadPool
.I know about the GIL. However, in my usecase, the function will be an IO-bound C function for which the python wrapper will release the GIL before the actual function call.
?Respostas:
Acabei de descobrir que realmente existe uma interface Pool baseada em encadeamento no
multiprocessing
módulo, no entanto, ela está oculta e não está documentada corretamente.Pode ser importado via
Ele é implementado usando uma classe fictícia Process que envolve um encadeamento python. Essa classe Process baseada em encadeamento pode ser encontrada na
multiprocessing.dummy
qual é mencionada brevemente nos documentos . Este módulo fictício supostamente fornece toda a interface de multiprocessamento baseada em threads.fonte
multiprocessing.dummy.Pool
/multiprocessing.pool.ThreadPool
são a mesma coisa e são ambos conjuntos de threads. Eles imitam a interface de um pool de processos, mas são implementados inteiramente em termos de encadeamento. Releia os documentos, você conseguiu o contrário.multiprocessing.dummy
replica a API,multiprocessing
mas não passa de um invólucro ao redor dothreading
módulo".multiprocessing
em geral, trata-se de processos, mas, para permitir a alternância entre processos e encadeamentos, eles (principalmente) replicaram amultiprocessing
APImultiprocessing.dummy
, mas fizeram backup com encadeamentos, não processos. O objetivo é permitir que vocêimport multiprocessing.dummy as multiprocessing
altere o código baseado em processo para baseado em encadeamento.No Python 3 você pode usar
concurrent.futures.ThreadPoolExecutor
, ou seja:Veja os documentos para mais informações e exemplos.
fonte
sudo pip install futures
ThreadPoolExecutor
emultiprocessing.dummy.Pool
?Sim, e parece ter (mais ou menos) a mesma API.
fonte
ThreadPool
é diferente dePool
. A importação correta éfrom multiprocessing.pool import ThreadPool
.Para algo muito simples e leve (ligeiramente modificado a partir daqui ):
Para oferecer suporte a retornos de chamada na conclusão da tarefa, basta adicionar o retorno de chamada à tupla da tarefa.
fonte
Queue.get()
está bloqueando) até o programa terminar, após o que são finalizados automaticamente.Queue.join()
realmente ingressará na fila de tarefas, não nos threads de trabalho. Portanto, quando a fila está vazia, oswait_completion
retornos, o programa são finalizados e os threads são colhidos pelo sistema operacional.pool.wait_completion()
retornar. O resultado é que os threads continuam construindo.Olá, para usar o pool de threads no Python, você pode usar esta biblioteca:
e, para uso, esta biblioteca faz o seguinte:
Os threads são o número de threads que você deseja e as tarefas são uma lista das tarefas que mais são mapeadas para o serviço.
fonte
.close()
e.join()
chamadas e que as causas.map()
para terminar antes de todos os fios estão acabados. Apenas um aviso.Aqui está o resultado que finalmente acabei usando. É uma versão modificada das classes por dgorissen acima.
Arquivo:
threadpool.py
Para usar a piscina
fonte
#!/usr/bin/python3
)for i, d in enumerate(delays):
e depois ignora oi
valor?i
durante uma execução.create_task
existe? Para que serve?A sobrecarga de criação dos novos processos é mínima, especialmente quando são apenas quatro deles. Duvido que este seja um hot spot de desempenho do seu aplicativo. Mantenha-o simples, otimize para onde você precisa e para onde os resultados de criação de perfil apontam.
fonte
Não existe um pool baseado em encadeamento. No entanto, pode ser muito rápido implementar uma fila de produtores / consumidores com a
Queue
classe.De: https://docs.python.org/2/library/queue.html
fonte
concurrent.futures
módulo.from multiprocessing.pool import ThreadPool
outra maneira pode ser adicionar o processo ao pool de filas
fonte