Коли слід викликати multiprocessing.Pool.join?


96

Я використовую 'multiprocess.Pool.imap_unordered' наступним чином

from multiprocessing import Pool
pool = Pool()
for mapped_result in pool.imap_unordered(mapping_func, args_iter):
    do some additional processing on mapped_result

Чи потрібно мені телефонувати pool.closeабо pool.joinпісля циклу for?


Я зазвичай телефоную pool.join()тоді, pool.close()як тільки я запустив усі потоки пулу, але я не намагався використовувати pool.imap_unordered()як ітерабельний.
Bamcclur

8
який сенс закликати приєднатися чи закрити? Я їм не дзвонив, і мій код, здається, працює нормально. Однак я стурбований тим, що не викликати їх призведе до процесів зомбі або інших тонких речей.
hch

Відповіді:


113

Ні, ні, але це, мабуть, гарна ідея, якщо ви більше не збираєтесь користуватися басейном.

Причини дзвінка pool.closeабо pool.joinдобре сказані Тімом Пітерсом у цій публікації SO :

Що стосується Pool.close (), ви повинні викликати це, коли - і лише коли - ви ніколи не збираєтеся подавати більше роботи до екземпляра Pool. Отже, Pool.close (), як правило, викликається, коли паралелізується частина вашої основної програми закінчена. Тоді робочі процеси припиняться, коли завершиться вся вже призначена робота.

Також чудова практика - зателефонувати Pool.join (), щоб дочекатися завершення робочих процесів. Серед інших причин, часто немає хорошого способу повідомити про винятки в паралелізованому коді (винятки трапляються в контексті, який лише неясно пов'язаний з тим, що робить ваша основна програма), а Pool.join () забезпечує точку синхронізації, яка може повідомляти про деякі винятки, що мали місце у робочих процесах, яких ви б ніколи не бачили.


9
чи краще дзвонити одному перед іншим?
RSHAP

9
Здається, люди люблять дзвонити pool.close()першим і pool.join()другим. Це дозволяє вам додавати роботу між pool.close()і pool.join()тим, що не потрібно чекати, поки пул закінчить виконання.
Bamcclur

34
Просто додати коментар @ Bamcclur - це не просто гарна ідея зателефонувати pool.close()першим, це насправді обов’язково. З документації : Потрібно зателефонувати close()або terminate()перед використанням join().
Bogd

4
@Bogd Але чому це обов’язково? Не могли б ви відповісти на це запитання, будь ласка?
agdhruv

Відповідь на питання agdhruvs була б чудовою!
Батогом

44

У мене була така ж проблема пам'яті в якості використання пам'яті постійно зростає з multiprocessing.pool Пайтона , коли я не використовував pool.close()і pool.join()при використанні pool.map()з функцією , яка обчислюється відстань Левенштейна. Функція працювала нормально, але сміття не збиралося належним чином на машині Win7 64, і використання пам’яті все більше виходило з-під контролю при кожному виклику функції, поки вона не вивела з ладу всю операційну систему. Ось код, який виправив витік:

stringList = []
for possible_string in stringArray:
    stringList.append((searchString,possible_string))

pool = Pool(5)
results = pool.map(myLevenshteinFunction, stringList)
pool.close()
pool.join()

Після закриття та приєднання до пулу витік пам'яті зник.


1
я отримував ERROR: Terminated with signal 15до того, як додав код очищення, pool.close();pool.join();але після додавання цього коду очищення я не отримую повідомлень консолі. тому я підозрюю принаймні у моїй версії, python 2.7 з C7, що басейн, можливо, якось не прибирався точно.
Тревор Бойд Сміт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.