Поймать исключение в работнике пула, которое еще не запущено

1

Я пытаюсь поймать исключение в подпроцессе. Мой код (см. Ниже) работает отлично, если число работников == количество задач. Но если работники больше, чем задачи, как в примере, 2 процесс, который еще не был запущен, будет иметь такое же исключение, но я не могу его поймать ни в MainProcess, ни в подпроцессах.

from multiprocessing import Pool, current_process
import time
from exceptions import GracefulExit
import signal


def terminate_handler(signum, frame):
    print(dir(frame))
    if current_process().name == 'MainProcess':
        # we will not raise error if process
        # is main because we need to finish all the jobs
        return
    raise GracefulExit()


def test_func(val):
    i = 0
    try:
        while True:
            time.sleep(0.1)
            i += 1
            if i >= 10:
                return i
    except GracefulExit:
        pass
    return i


if __name__ == "__main__":
    signal.signal(
            signal.SIGINT, terminate_handler)
    try:
        with Pool(5) as p:
            r = p.map(test_func, [1, 2, 3])
    except GracefulExit:
        pass
    print(r)
  • 0
    Вы не могли бы просто сделать функцию GracefulExit() которая обрабатывает выход, вместо того, чтобы вызывать исключение?
  • 0
    Затем я должен использовать некоторую структуру синхронизации для управления нажатием Ctrl + C. Это возможно, но гораздо медленнее. Благодарю.
Теги:
multiprocessing

1 ответ

1

Что я могу предложить, выберите любой вариант:

  1. убедитесь, что количество заданий не меньше числа рабочих, просто добавьте заглушки (например, " None), чтобы обеспечить запуск всех работников

  2. переопределять run метод процесса пула:

    class CustomProcess(Process):
        def run(self):
            try:
                super().run()
            except GracefulExit:
                print('interrupted idle worker')
    
    
    class CustomPool(multiprocessing.pool.Pool):
        Process = CustomProcess
    
    ....
    
    with CustomPool(5) as p:
       r = p.map(test_func, [1, 2, 3])
    
  3. написать собственную реализацию пула

Ещё вопросы

Сообщество Overcoder
Наверх
Меню