我正在使用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")
答案 0 :(得分:1)
executor.map()
不会引发错误,因为工作线程会在不引发错误的情况下以静默方式终止,除非您尝试根据docs从迭代器中检索结果:
map(func,* iterables,timeout = None,chunksize = 1)
如果函数调用引发异常,则将引发该异常 从迭代器中获取其值时。
您可以通过在返回的next()
上调用iterator
来验证这一点:
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!