Существует ли класс Pool для рабочих потоков , аналогичный классу пула многопроцессорного модуля ?
Мне нравится, например, простой способ распараллелить функцию карты
def long_running_func(p):
c_func_no_gil(p)
p = multiprocessing.Pool(4)
xs = p.map(long_running_func, range(100))
Однако я хотел бы сделать это без накладных расходов на создание новых процессов.
Я знаю о GIL. Однако в моем случае использования эта функция будет функцией C, связанной с вводом-выводом, для которой оболочка Python выпустит GIL перед фактическим вызовом функции.
Должен ли я написать свой собственный пул потоков?
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.
?Ответы:
Я только что узнал , что на самом деле это поток-интерфейс Бассейн в
multiprocessing
модуле, однако он скрыт несколько и не должным образом задокументированы.Это может быть импортировано через
Он реализован с использованием фиктивного класса Process, обертывающего поток Python. Этот основанный на потоках класс Process можно найти, в
multiprocessing.dummy
котором кратко упоминается в документации . Этот фиктивный модуль предположительно обеспечивает весь многопроцессорный интерфейс на основе потоков.источник
multiprocessing.dummy.Pool
/multiprocessing.pool.ThreadPool
это одно и то же, и оба являются пулами потоков. Они имитируют интерфейс пула процессов, но они полностью реализованы с точки зрения потоков. Перечитайте документы, вы получили это задом наперед.multiprocessing.dummy
API,multiprocessing
но является не более чем оболочкой вокругthreading
модуля».multiprocessing
В общем, речь идет о процессах, но чтобы разрешить переключение между процессами и потоками, они (в основном) реплицировалиmultiprocessing
APImultiprocessing.dummy
, но опирались на потоки, а не на процессы. Цель состоит в том, чтобы вы моглиimport multiprocessing.dummy as multiprocessing
изменить код, основанный на процессах, на поток.В Python 3 вы можете использовать
concurrent.futures.ThreadPoolExecutor
, то есть:Смотрите документы для получения дополнительной информации и примеров.
источник
sudo pip install futures
ThreadPoolExecutor
иmultiprocessing.dummy.Pool
?Да, и, кажется, (более или менее) тот же API.
источник
ThreadPool
отличается отPool
. Правильный импорт естьfrom multiprocessing.pool import ThreadPool
.Для чего-то очень простого и легкого (немного измененного отсюда ):
Для поддержки обратных вызовов при завершении задачи вы можете просто добавить обратный вызов в кортеж задачи.
источник
Queue.get()
блокируется) до завершения программы, после чего они автоматически завершаются.Queue.join()
фактически присоединится к очереди задач, а не к рабочим потокам. Таким образом, когда очередь пуста,wait_completion
возвращается, программа завершается, а потоки собираются в ОС.pool.wait_completion()
возвращается. В результате потоки просто продолжают строить.Привет, чтобы использовать пул потоков в Python, вы можете использовать эту библиотеку:
и затем для использования, эта библиотека делает так:
Потоки - это количество потоков, которые вы хотите, а задачи - это список задач, которые больше всего соответствуют сервису.
источник
.close()
и.join()
вызовы , и что причины ,.map()
чтобы закончить , прежде чем все нити закончены. Просто предупреждение.Вот результат, который я наконец-то использовал. Это модифицированная версия классов от dgorissen выше.
Файл:
threadpool.py
Использовать бассейн
источник
#!/usr/bin/python3
)for i, d in enumerate(delays):
а затем игнорироватьi
значение?i
во время пробежки.create_task
там? Для чего это?Затраты на создание новых процессов минимальны, особенно когда их всего 4. Я сомневаюсь, что это горячая точка производительности вашего приложения. Сохраняйте это простым, оптимизируйте, где вы должны и где указывают результаты профилирования.
источник
Нет встроенного пула на основе потоков. Тем не менее, это может быть очень быстро реализовать очередь производителя / потребителя с
Queue
классом.От: https://docs.python.org/2/library/queue.html
источник
concurrent.futures
модулю.from multiprocessing.pool import ThreadPool
другим способом может быть добавление процесса в пул очереди нитей
источник