Как собрать детей и выйти из многопроцессорного пула Python - PullRequest
1 голос
/ 27 апреля 2019

Что я пытаюсь сделать:

Когда возникает исключение после создания многопроцессорного пула, тогда дочерние процессы становятся зомби, когда родительский процесс завершается.Чтобы исправить это, я ловлю исключение, и явно пожинаю все дети в пуле.

Проблема в

, из-за которой родительский модуль зависает, а не выходит и возвращается в командную строку терминала.

Это последнее поведениенеожиданно и я не понимаю почему.Но трассировка указывает, что это проблема в пуле.

Вопрос почему это зависает?

import multiprocessing as mp

def deadPool():
    print("Everybody out of the pool")
    active = mp.active_children()
    for a in active:
        print("reaping",a)
        a.terminate()
    print('deadpool')

try:
    pool = mp.Pool(mp.cpu_count()//2)
    print (" running with pool of ",mp.cpu_count()//2)
    p = 1/0  # intentional bug to generate exception

finally:
    deadPool()

Вот вызовэтого:

python ~/Documents/testMp.py 
 running with pool of  4
Everybody out of the pool
reaping <ForkProcess(ForkPoolWorker-1, started daemon)>
reaping <ForkProcess(ForkPoolWorker-4, started daemon)>
reaping <ForkProcess(ForkPoolWorker-2, started daemon)>
reaping <ForkProcess(ForkPoolWorker-3, started daemon)>
deadpool
Traceback (most recent call last):
  File "/Users/foo/testMp.py", line 15, in <module>
    p = 1/0  # intentional bug 
ZeroDivisionError: division by zero

На этом этапе родительский процесс зависает.

нажатие клавиши Control-C, чтобы выйти из этого зависанияпроцесс лает из-за исключения клавиатуры и возвращается к окну терминала

^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/Users/foo/anaconda3/envs/jupyter2/lib/python3.7/multiprocessing/util.py", line 265, in _run_finalizers
    finalizer()
  File "/Users/foo/anaconda3/envs/jupyter2/lib/python3.7/multiprocessing/util.py", line 189, in __call__
    res = self._callback(*self._args, **self._kwargs)
  File "/Users/foo/anaconda3/envs/jupyter2/lib/python3.7/multiprocessing/pool.py", line 581, in _terminate_pool
    cls._help_stuff_finish(inqueue, task_handler, len(pool))
  File "/Users/foo/anaconda3/envs/jupyter2/lib/python3.7/multiprocessing/pool.py", line 566, in _help_stuff_finish
    inqueue._rlock.acquire()
KeyboardInterrupt

Как вы можете заметить, он застрял в «_terminate_pool», так что это как-то связано с многопроцессорностью

...