Принятый ответ гласит, что для imap_unordered
результаты будут получены, как только они будут готовы, из чего можно сделать вывод, что результаты будут возвращены в порядке завершения. Но я просто хочу прояснить, что это вообще неверно. В документации указано, что результаты возвращаются в произвольном порядке. Рассмотрим следующую программу, которая использует размер пула 4, размер iterable 20 и значение chunksize 5. Рабочая функция находится в состоянии ожидания разное количество времени в зависимости от ее переданный аргумент, который также гарантирует, что ни один процесс в пуле не захватит все отправленные задачи. Таким образом, я ожидаю, что каждый процесс в пуле будет иметь 20 / 4 = 5
задачи для обработки:
from multiprocessing import Pool
import time
def worker(x):
print(f'x = {x}', flush=True)
time.sleep(.1 * (20 - x))
# return approximate completion time with passed argument:
return time.time(), x
if __name__ == '__main__':
pool = Pool(4)
results = pool.imap_unordered(worker, range(20), chunksize=5)
for t, x in results:
print('result:', t, x)
Отпечатки:
x = 0
x = 5
x = 10
x = 15
x = 16
x = 17
x = 11
x = 18
x = 19
x = 6
result: 1621512513.7737606 15
result: 1621512514.1747007 16
result: 1621512514.4758775 17
result: 1621512514.675989 18
result: 1621512514.7766125 19
x = 12
x = 1
x = 13
x = 7
x = 14
x = 2
result: 1621512514.2716103 10
result: 1621512515.1721854 11
result: 1621512515.9727488 12
result: 1621512516.6744206 13
result: 1621512517.276999 14
x = 8
x = 9
x = 3
result: 1621512514.7695887 5
result: 1621512516.170747 6
result: 1621512517.4713914 7
result: 1621512518.6734042 8
result: 1621512519.7743165 9
x = 4
result: 1621512515.268784 0
result: 1621512517.1698637 1
result: 1621512518.9698756 2
result: 1621512520.671273 3
result: 1621512522.2716706 4
Вы можете ясно видеть, что эти результаты не выдаются в порядке завершения. Например, мне было возвращено 1621512519.7743165 9
, за которым следует 1621512515.268784 0
, которое было возвращено рабочей функцией более чем на 4 секунды раньше, чем ранее возвращенный результат. Однако, если я изменю значение chunksize на 1, распечатка станет такой:
x = 0
x = 1
x = 2
x = 3
x = 4
result: 1621513028.888357 3
x = 5
result: 1621513028.9863524 2
x = 6
result: 1621513029.0838938 1
x = 7
result: 1621513029.1825204 0
x = 8
result: 1621513030.4842813 7
x = 9
result: 1621513030.4852195 6
x = 10
result: 1621513030.4872172 5
x = 11
result: 1621513030.4892178 4
x = 12
result: 1621513031.3908074 11
x = 13
result: 1621513031.4895358 10
x = 14
result: 1621513031.587289 9
x = 15
result: 1621513031.686152 8
x = 16
result: 1621513032.1877549 15
x = 17
result: 1621513032.1896958 14
x = 18
result: 1621513032.1923752 13
x = 19
result: 1621513032.1923752 12
result: 1621513032.2935638 19
result: 1621513032.3927407 18
result: 1621513032.4912949 17
result: 1621513032.5884912 16
Это находится в порядке завершения. Однако я не решаюсь утверждать, что imap_unordered
всегда будет возвращать результаты по мере их появления, если указано значение chunksize, равное 1, хотя это кажется быть случай, основанный на этом эксперименте, поскольку документация не делает такого заявления.
Обсуждение
Когда указан chunksize, равный 5, 20 задач помещаются в одну входную очередь, чтобы 4 процесса в пуле обрабатывали их фрагментами размером 5. Таким образом, простаивающий процесс отключается. поставьте в очередь следующий блок из 5 задач и обработайте каждую из них по очереди, прежде чем снова станет бездействующим. Таким образом, первый процесс будет обрабатывать x
аргументов от 0 до 4, второй процесс — x
аргументов от 5 до 9 и т. д. Вот почему вы видите начальные x
значений, напечатанных как 0, 5, 10 и 15.
Но хотя результат для x
аргумента 0 завершается раньше, чем результат для x
аргумента 9, может показаться, что результаты записываются вместе как фрагменты, и поэтому результат для x
аргумента 0 не будет возвращен до тех пор, пока не будут получены результаты для x
аргументов, поставленных в очередь. вверх в том же фрагменте (т. е. 1, 2, 3 и 4) также доступны.
person
Booboo
schedule
20.05.2021