2014-02-19 2 views
0

У меня есть приложение, которое запускает подпроцессы (в настоящее время 64) и выполняет некоторую работу. Каждый процесс заканчивается примерно через 45 минут, но каким-то образом родительский процесс, кажется, зависает, потому что родительский процесс не выходит и не зависает в цикле соединения.Подпроцессы завершены, но родительский процесс зависает

я начинаю proccesses так:

def worker(out_q): 
    # do something that takes a lot of time 
    print('done working') 
    sys.exit(0) 

def main(): 
    procs = [] 
    out_q = Queue() 

    for i in range(opt.num_threads): 
     sys.stdout.write("\r\tStarting Worker Process: %d" %(i+1)) 
     sys.stdout.flush() 
     p = multiprocessing.Process(target=worker, args=(out_q,)) 
     procs.append(p) 
     p.start() 

    #then i wait for all processes to finish: 

    try: 
     for i, p in enumerate(procs): 
      print("waiting for process %d" %i) 
      p.join() 
      print("process %d joined" %i) 
    except KeyboardInterrupt as e: 
     sys.exit(0) 
if __name__ == "__main__": 
    main() 

единственный выход я вижу waiting for process 0 и после того, как сделаны все процессы (я вижу все процессы говорят done working, есть еще все 64 процессов в списке процессов и родительский процесс не завершается. Кажется, что родительский процесс повесил трубку, потому что он не может быть убит диспетчером задач.

Как я могу отлаживать это или мне нужно убить процесс? удаляться из списка процессов после вызова sys.exit (0) ins образ ребенка?

+0

Рабочие ставят что-то в 'out_q'? Вы потребляете очередь? –

+0

да, они делают. я видел это здесь http://bugs.python.org/issue8237 Теперь я проверяю, как полно очередь очереди, и попытайтесь реализовать очередную промывку ... – reox

ответ

0

Это не может быть прямой причиной зависания.

Вам необходимо передать args как кортеж (out_q,) или как список [out_q].

p = multiprocessing.Process(target=worker, args=(out_q,)) 
#            ^^^^^^^ 
+0

ах нет, это просто ошибка копирования и вставки ... у рабочего больше аргументов, и я разделил их. все это работает, если время работы короче. поэтому эта проблема возникает только при длительном времени выполнения> 10min – reox

+0

@reox, защищаете ли вы код, связанный с несколькими процессами, с 'if __name__ == '__main__': ..'? – falsetru

+0

да, я добавлю это в код, который я разместил. – reox

1

Вы не должны делать exit(0) в функции worker. Это убивает ваш подпроцесс, прежде чем у него появится шанс сообщить об этом успеху родителям. Другими словами, подпроцесс убивается до вызова task_done(), таким образом p.join() будет ждать всегда.

+0

, но рабочий не убит - я вижу изображение процесса в procexplorer. Даже если я не делаю sys.exit (0), родительский процесс зависает в этом цикле ... Я попробую еще раз без sys.exit (0) - может занять некоторое время – reox

+0

@reox: Вы тестируете свой многопроцессорный код, комментируя трудоемкую часть? – vartec

+0

, потому что тогда все работает нормально;) так же, как сказано: проблема возникает только в том случае, если я позволяю ей работать некоторое время. Я подумал о проблеме во временной части, но по мере того как каждый процесс достигает конца и сообщает, что это сделано, я не думаю, что проблема в том, что проблема – reox

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