Я попытался прочитать документацию на http://docs.python.org/dev/library/multiprocessing.html, но все еще борюсь с многопроцессорной обработкой Queue, Pool и Locking. А пока мне удалось построить пример ниже.
Что касается очереди и пула, я не уверен, правильно ли я понял эту концепцию, поэтому поправьте меня, если я ошибаюсь. Я пытаюсь обработать 2 запроса за раз (в этом примере в списке данных 8), так что мне следует использовать? Пул для создания 2 процессов, которые могут обрабатывать две разные очереди (максимум 2), или я должен просто использовать Queue для обработки 2 входов каждый раз? Блокировка заключалась бы в правильной печати выходных данных.
import multiprocessing
import time
data = (['a', '2'], ['b', '4'], ['c', '6'], ['d', '8'],
['e', '1'], ['f', '3'], ['g', '5'], ['h', '7']
)
def mp_handler(var1):
for indata in var1:
p = multiprocessing.Process(target=mp_worker, args=(indata[0], indata[1]))
p.start()
def mp_worker(inputs, the_time):
print " Processs %s\tWaiting %s seconds" % (inputs, the_time)
time.sleep(int(the_time))
print " Process %s\tDONE" % inputs
if __name__ == '__main__':
mp_handler(data)
источник
var1
полностью,data
вместо этого ссылаясь на global .Это может быть не на 100% связано с вопросом, но в моем поиске примера использования многопроцессорной обработки с очередью это сначала появляется в Google.
Это базовый пример класса, который вы можете создавать и помещать элементы в очередь, а также можете ждать, пока очередь не будет завершена. Это все, что мне нужно.
from multiprocessing import JoinableQueue from multiprocessing.context import Process class Renderer: queue = None def __init__(self, nb_workers=2): self.queue = JoinableQueue() self.processes = [Process(target=self.upload) for i in range(nb_workers)] for p in self.processes: p.start() def render(self, item): self.queue.put(item) def upload(self): while True: item = self.queue.get() if item is None: break # process your item here self.queue.task_done() def terminate(self): """ wait until queue is empty and terminate processes """ self.queue.join() for p in self.processes: p.terminate() r = Renderer() r.render(item1) r.render(item2) r.terminate()
источник
item1
иitem2
? Это какая-то задача или функции, которые будут выполняться в двух разных процессах?Вот моя личная инструкция по этой теме:
Суть здесь (запросы на включение приветствуются!): Https://gist.github.com/thorsummoner/b5b1dfcff7e7fdd334ec
import multiprocessing import sys THREADS = 3 # Used to prevent multiple threads from mixing thier output GLOBALLOCK = multiprocessing.Lock() def func_worker(args): """This function will be called by each thread. This function can not be a class method. """ # Expand list of args into named args. str1, str2 = args del args # Work # ... # Serial-only Portion GLOBALLOCK.acquire() print(str1) print(str2) GLOBALLOCK.release() def main(argp=None): """Multiprocessing Spawn Example """ # Create the number of threads you want pool = multiprocessing.Pool(THREADS) # Define two jobs, each with two args. func_args = [ ('Hello', 'World',), ('Goodbye', 'World',), ] try: # Spawn up to 9999999 jobs, I think this is the maximum possible. # I do not know what happens if you exceed this. pool.map_async(func_worker, func_args).get(9999999) except KeyboardInterrupt: # Allow ^C to interrupt from any thread. sys.stdout.write('\033[0m') sys.stdout.write('User Interupt\n') pool.close() if __name__ == '__main__': main()
источник
get()
является тайм-аут, он не имеет ничего общего с количеством запущенных заданий..get(timeout=1)
? и можно ли просто сказать,.get()
чтобы получить полный список?.get()
ожидает бесконечно, пока не будут доступны все результаты, и возвращает список результатов. Вы можете использовать цикл опроса для проверки доступности результатов погоды или передать вmap_async()
вызове функцию обратного вызова, которая затем будет вызываться для каждого результата, когда он станет доступным.Для всех, кто использует такие редакторы, как Komodo Edit (win10), добавьте
sys.stdout.flush()
в:def mp_worker((inputs, the_time)): print " Process %s\tWaiting %s seconds" % (inputs, the_time) time.sleep(int(the_time)) print " Process %s\tDONE" % inputs sys.stdout.flush()
или как первая строка:
if __name__ == '__main__': sys.stdout.flush()
Это помогает увидеть, что происходит во время выполнения сценария; вместо того, чтобы смотреть на черное поле командной строки.
источник
Вот пример из моего кода (для пула потоков, но просто измените имя класса, и у вас будет пул процессов):
def execute_run(rp): ... do something pool = ThreadPoolExecutor(6) for mat in TESTED_MATERIAL: for en in TESTED_ENERGIES: for ecut in TESTED_E_CUT: rp = RunParams( simulations, DEST_DIR, PARTICLE, mat, 960, 0.125, ecut, en ) pool.submit(execute_run, rp) pool.join()
В принципе:
pool = ThreadPoolExecutor(6)
создает пул на 6 потоковpool.submit(execute_run, rp)
добавляет задачу в пул, первый аргумент - это функция, вызываемая в потоке / процессе, остальные аргументы передаются вызываемой функции.pool.join
ждет, пока все задачи не будут выполнены.источник
concurrent.futures
, но OP спрашивает оmultiprocessing
Python 2.7.