2016-02-29 8 views
2

Я ударяю головой уже более дня, пытаясь понять, почему дети моей программы не могут вызвать какое-либо исключение и просто умереть, вместо того, чтобы зависеть целое Pool. Позвольте мне добавить, что я обыскал в Интернете часами, не нашел чего-то связанного.Карта пула Python висит, когда подпроцесс убит

Давайте рассмотрим в качестве примера:

#!/opt/perforce/bin/python/3.4.2/bin/python3 

import multiprocessing 
import sys 


def run(i): 
    print(i) 
    sys.exit(1) 

iteration = ['test1', 'test2', 'test3'] 

with multiprocessing.Pool(1) as pool: 
    pool.map(run, iteration) 
    print("reached here ?") 

с sys.exit(), печать никогда не достигается, pool.map вешает блоки по некоторым причинам. На моем подлинном скрипте добавлен sys.exit(), когда я поймаю какие-то ошибки. Я хотел бы умело убить рабочего (или просто пропустить итерацию, как перерыв). Я пробовал sys.exit(), exit() или даже os.kill(), но не повезло ...

Возможно ли это?

+0

Которая 'print' не достигнута? Тот, который говорит, «достигнут здесь?» или один (ы) внутри 'run()'? – DaveBensonPhillips

+0

принт «достигнут здесь?». Мне интересно, почему мой pool.map никогда не заканчивается. :) –

ответ

0

Я предлагаю, вы поднимаете Исключение и ловите его за пределами вызываемого. Пример:

import multiprocessing 
import sys 


def run(i): 
    print(i) 
    if i == 'test3': 
     raise Exception() 

iteration = ['test1', 'test2', 'test3'] 

with multiprocessing.Pool(1) as pool: 
    try: 
     result = pool.map(run, iteration) 
    except Exception: 
     sys.exit(1) 
    print("reached here ?") 
+0

На самом деле я не хочу выходить из всего пула, как вам кажется. В противном случае я бы использовал pool.terminate. Я просто хочу, чтобы текущая итерация проходила и умирала, не блокируя весь пул. –

+2

@GuillaumeFenollar 'Pool.map()' предназначен для * безопасности *. И если вы запустите его по N элементам, он должен вернуть N результатов. Если дочерний процесс умирает тем временем, то что-то пошло не так. Подумайте о том, чтобы уловить исключения в дочернем процессе и вернуть значение ошибки вместо того, чтобы убить весь дочерний процесс (который чувствует себя неправильно, ИМО). –

+0

Он действительно работает с набором возвратов, когда у моего подпроцесса есть проблема. Это немного уродливо, потому что у меня есть большое дерево функций, и я должен использовать несколько возвратов, чтобы вернуться к моей функции __main__, где запущен pool.map, но он работает. Я понимаю вашу точку зрения, но я до сих пор жалею, что нет способа изящно прекратить процесс pool.map (как это существует с Process.terminate()). Спасибо Ярослав –

Смежные вопросы