tl; dr Я создаю 3 потока, каждая нить генерирует исключение, большинство pythonic способ поднять все 3 исключения?Получение нескольких исключений из потоков в Python
Ниже приведен пример кода, аналогичный тому, что я делаю.
from multiprocessing.pool import ThreadPool
def fail_func(host):
raise Exception('{} FAILED!!!'.format(host))
hosts = ['172.1.1.1', '172.1.1.2', '172.1.1.3']
pool = ThreadPool(processes=5)
workers = [pool.apply_async(fail_func(host)) for host in hosts]
# join and close thread pool
pool.join(); pool.close()
# get the exceptions
[worker.get() for worker in workers if not worker.successful()]
Что это заканчивает тем, что делает это просто провал на 1 хост со следующим TRACEBACK:
Но я хочу, чтобы это сделать, это поднять несколько исключений для каждого из потоков, которые не удалось, как и :
Traceback (most recent call last):
File "thread_exception_example.py", line 8, in <module>
workers = [pool.apply_async(fail_func(host)) for host in hosts]
File "thread_exception_example.py", line 4, in fail_func
raise Exception('{} FAILED!!!'.format(host))
Exception: 172.1.1.1 FAILED!!!
Traceback (most recent call last):
File "thread_exception_example.py", line 8, in <module>
workers = [pool.apply_async(fail_func(host)) for host in hosts]
File "thread_exception_example.py", line 4, in fail_func
raise Exception('{} FAILED!!!'.format(host))
Exception: 172.1.1.2 FAILED!!!
Traceback (most recent call last):
File "thread_exception_example.py", line 8, in <module>
workers = [pool.apply_async(fail_func(host)) for host in hosts]
File "thread_exception_example.py", line 4, in fail_func
raise Exception('{} FAILED!!!'.format(host))
Exception: 172.1.1.3 FAILED!!!
Есть ли какой-нибудь питонический способ сделать это? или мне нужно обернуть все в try/except, собрать все сообщения, а затем повторно создать одно исключение?
В качестве побочного примечания, это немного запутанно называть ваши объекты результатов «работником». Обычно это слово относится к подпроцессам в пуле. – abarnert
В качестве еще одной заметки «multiprocessing.pool.ThreadPool» является недокументированной функцией, а «multiprocessing.dummy.Pool» документирован и должен предоставить вам то, что вы хотите. Я лично считаю, что в этом случае гораздо более ясное название 'ThreadPool' и' dummy.Pool' перевешивает это, но это стоит знать выбор для себя. – abarnert