YardalGedal
@YardalGedal
yeah boy

Как получить traceback в процеcсе multiprocessing?

И так, какая-то шаманская проблема. Имеем вот такой код, который сам по себе запускается в пуле процессов multiprocessing.dummy (то есть run() запущен почти так же, как порождает новые процессы, в нём видно как он это делает)
Как запускается run
class Main:
    delay = 60

    def __init__(self):
        while 1:
            tasks = getting_tasks_f()

            if tasks:
                p = Pool(min(cpu_count(), len(tasks)))
                p.map_async(self.run_task, tasks)
                p.close()

            tools.pause(self.delay)

    def run_task(self, data: dict):
        task = any_actions_with_data_f(data)

        try:
            task.run()
        except Exception as e:
            print(task, e)


Это к проблеме имеет косвенное отношение, хотя на всякий случай код оставил под катом.
Едем далее:
class Do(Task):
    def run(self):
        tasks = any_get_tasks_f()

        if tasks:
            p = Pool(min(cpu_count(), len(tasks)))
            p.map_async(self.do, tasks)
            p.close()

    def do(self, task):
        try:
            any_f(task)
        except Exception as e:
            print(1.1)
            print(''.join(traceback.format_exception(*sys.exc_info())), 1)
            print(1.3)

И так, проблема в том, что в do() исключения не ловятся в принципе, то есть никак. Если я в run() выкину исключение - я без проблем получаю о нём информацию уровнем выше. Если исключение происходит в do() - я не вижу ничего. Никаких принтов абсолютно. Если я поставлю print() try - он успешно выведется.
Это не ситуативная загвоздка, которую можно обойти:
в any_f() я нащупал, где кроется загвоздка - код отлично выполняется до вызова метода run(), все принты работают, всё окей, однако далее опять просто обрыв, никаких исключений, никакой информации после выполнения self.command.run()
def any_f(self):
        ...
        self.command = self.command(self)
        self.pay_bill()
        try:
            self.command.run()
        except Exception as e:
            print(2.1)
            print(''.join(traceback.format_exception(*sys.exc_info())), 2)
            print(2.3)
        self.prepare()
  • Вопрос задан
  • 119 просмотров
Решения вопроса 1
YardalGedal
@YardalGedal Автор вопроса
yeah boy
p.join() в данном случае сработал, но это не даёт понимания почему трейсбеки не возвращаются :(
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@bbkmzzzz
Все ловится, но не попадает в stderr
попробуйте так
import sys
import traceback
try:
    10 / 0
except:
    print(traceback.format_exc(10), file=sys.stderr)  # где 10 - максимальная глубина стека
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы