Буферизация вывода не является проблемой (или, по крайней мере, не единственной), потому что (a) сам процесс Python растет в памяти, и (b) если вы перенаправляете на /dev/null
, это все равно происходит.
Я думаю, что проблема в том, что когда вы распечатываете результаты, пул возвращает результаты гораздо быстрее, чем они могут быть использованы, и поэтому в памяти остается множество результатов. Если вы посмотрите на источник класса, который делает это , промежуточные результаты будут сохранены в collections.deque
, называемом _items
; Держу пари, что _items
становится огромным.
Я не совсем уверен, как это проверить, потому что, хотя imap_unordered
возвращает экземпляр этого класса , вы все равно, похоже, сможете получить только методы генератора:
In [8]: r = pool.imap_unordered(f, sampleiter(1e8), 20)
In [9]: print dir(r)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__',
'__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
Обновление: Если вы добавите time.sleep(.01)
к f()
, использование памяти останется полностью постоянным. Итак, проблема в том, что вы производите результаты быстрее, чем можете их использовать.
(В качестве отступления: вы имеете в виду pool.close()
в конце примера кода; pool.close
- это просто ссылка на функцию и фактически не вызывает ее.)