Как запустить задачу после завершения всех обратных вызовов

#python #python-3.x #multithreading #multiprocessing

Вопрос:

Я использую python 3 одновременно.фьючерсы.

 with concurrent.futures.ProcessPoolExecutor(max_workers=os.cpu_count()) as executor:
    futures = [executor.submit(do_the_work, item) for item in work_list.items()]
    for i, future in enumerate(concurrent.futures.as_completed(futures)):
        status = future.result()
        print('DONE: count:{} result:{}'.format(i, status))
 

Мой код был написан таким образом. Но теперь мне нужно выполнить задачу после того, как все фьючерсы будут завершены. Эти фьючерсы записывают данные в общую структуру данных. Поэтому после того, как все эти фьючерсы будут завершены, мне нужно обработать общую структуру данных.

Я думаю, что смогу переписать код, используя другую конструкцию потоковой передачи. Однако мне интересно, есть ли способ решить эту проблему с помощью concurrent.futures?

Комментарии:

1. Вам нужно использовать стандартную терминологию. В коде, который вы опубликовали, нет никаких «обратных вызовов». и вы не «продеваете нитку». Вы имеете в виду, что хотите отправить новую задачу после завершения всех фьючерсов? Если это так, то, все еще находясь в with блоке , выполните другой метод (например map submit , executor и т.д.) Для объекта. Если вы имеете в виду что-то другое, уточните свой вопрос. И почему вы используете enumerate , когда вы вообще не используете i переменную?

2. @Booboo обновил текст.

Ответ №1:

Как я уже говорил, после того, как ваш for цикл завершится, все ваши фьючерсы будут завершены. Теперь вы можете, если хотите, в том же with блоке отправлять дополнительные задачи в пул. Ниже я использую map метод вычисления квадрата из 10 чисел и печати результатов. Кстати, вы могли бы сами воспользоваться методом карты.

 with concurrent.futures.ProcessPoolExecutor(max_workers=os.cpu_count()) as executor:
    for i, status in enumerate(executor.map(do_the_work, work_list.items())):
        print('DONE: count:{} result:{}'.format(i, status))
 

Но, конечно, результаты будут возвращены в порядке представленных товаров, а не в порядке выполнения.

И выполнять дополнительные задачи:

 import concurrent.futures

def square_number(x):
    return x ** 2

with concurrent.futures.ProcessPoolExecutor(max_workers=os.cpu_count()) as executor:
    futures = [executor.submit(do_the_work, item) for item in work_list.items()]
    for i, future in enumerate(concurrent.futures.as_completed(futures)):
        status = future.result()
        print('DONE: count:{} result:{}'.format(i, status))
    print(list(executor.map(square_number, range(10))))