2013-08-16 3 views
2

tl; dr 나는 3 개의 스레드를 생성합니다. 각 스레드는 예외를 던집니다. 가장 예외적으로 모든 3 개의 예외를 발생시킵니다.파이썬의 스레드에서 여러 개의 예외 발생시키기

다음은 현재 수행중인 것과 비슷한 코드 예제입니다.

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 (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에서 모든 것을 래핑 할 필요가 있습니까? 모든 메시지를 수집 한 다음 단일 예외를 다시 발생시킵니다.

+0

결과 메모를 'worker'라고 부르는 것은 다소 혼란 스럽습니다. 일반적으로 해당 단어는 풀의 하위 프로세스를 나타냅니다. – abarnert

+0

또 다른 부수적으로'multiprocessing.pool.ThreadPool'은 문서화되지 않은 기능이며,'multiprocessing.dummy.Pool'은 문서화되어 있으며 원하는 것을 제공해야합니다. 나는 개인적으로이 경우 훨씬 더 명확한 이름 인'ThreadPool'과'dummy.Pool'이 그것을 능가한다고 생각합니다. 그러나 자신을위한 선택을 아는 것이 중요합니다. – abarnert

답변

2

"여러 예외 발생"방법이 없습니다. 주어진 예외 상황에서 예외가 있거나없는 것입니다.

그렇습니다. 모든 예외를 보유하는 래퍼 예외를 만들어야합니다. 당신이 단지 수 있습니다 ...

[worker.get() for worker in workers if not worker.successful()] 

: 대신, 이제

def get_exception(): 
    try: 
     worker.get() 
    except Exception as e: 
     return e 

:하지만 당신은 거의 당신이 필요로하는 모든 코드를 가지고

[get_exception(worker.get) for worker in workers if not worker.successful()] 

그리고 그 예외 목록입니다 .


개인적으로, 나는 항상 AsyncResultconcurrent.futures.Future에있는 것과 유사한 exception 방법을 가지고해야한다고 생각했습니다. 그렇다면 처음에는 futures을 사용했을 것입니다. (파이썬 2.x를 사용해야 만한다면 backport을 설치하십시오.)

관련 문제