在Python中如何处理线程内的错误?

2024-10-01 19:27:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用ThreadPoolExecutor执行一个导致错误的函数。当一个线程内发生错误(并且错误未被处理)时,它看起来像是在终止该线程,但没有将任何内容打印到stderr或导致程序崩溃。为什么会这样?我是否可以使任何线程中未经处理的错误导致整个程序崩溃?或者它可以打印在某个地方,这样我就可以看到发生了什么。你知道吗

我注意到这个错误可以在try-catch块中捕获,所以它肯定会被抛出。如果在没有线程的情况下调用相同的函数,则会按预期引发错误。你知道吗

from concurrent.futures import ThreadPoolExecutor
import time


def error_causer(x):
    print(x)
    raise ValueError("This bad!")


with ThreadPoolExecutor(max_workers=1) as executor:
    executor.map(error_causer, ["coming from thread"])

print("After don't catch. Should have crashed by now...")
time.sleep(2)

error_causer("coming from outside thread")

当ValueError在线程内引发时,该程序不会崩溃,但当ValueError在线程外引发时,该程序会崩溃。你知道吗

输出为:

coming from thread
After don't catch. Should have crashed by now...
coming from outside thread
Traceback (most recent call last):
  File "./another_threading_test.py", line 16, in <module>
    error_causer("coming from outside thread")
  File "./another_threading_test.py", line 7, in error_causer
    raise ValueError("This bad!")
ValueError: This bad!

我希望它在print("after don't catch")之前崩溃


Tags: from程序错误errorthis线程threadbad
1条回答
网友
1楼 · 发布于 2024-10-01 19:27:03

executor.map()不会引发错误,因为工作线程是在不引发错误的情况下静默终止的,除非您尝试从迭代器中检索结果这是根据docs

map(func, *iterables, timeout=None, chunksize=1)

If a func call raises an exception, then that exception will be raised when its value is retrieved from the iterator.

您可以通过调用返回的iterator上的next()来验证这一点:

def error_causer(x):
    print(x)
    raise ValueError("This bad!")


with ThreadPoolExecutor(max_workers=1) as executor:
    iterator = executor.map(error_causer, ["coming from thread"])
    next(iterator)

现在,在调用迭代器上的next()之后,您将看到在主线程中引发的错误来自终止主线程的工作线程:

Traceback (most recent call last):
  File "/Users/ambhowmi/PycharmProjects/Datastructures/TwoStacksQueue.py", line 13, in <module>
    next(iterator)
  File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 598, in result_iterator
    yield fs.pop().result()
  File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 428, in result
    return self.__get_result()
  File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result
    raise self._exception
  File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/Users/ambhowmi/PycharmProjects/Datastructures/TwoStacksQueue.py", line 8, in error_causer
    raise ValueError("This bad!")
ValueError: This bad!

相关问题 更多 >

    热门问题