【发布时间】:2020-03-04 21:41:45
【问题描述】:
注意:我的问题在副本中有one exact answer(另请参阅下面的修改代码的答案)。谢谢@quamrana 的指点
上下文:我有一个类中的方法列表,这些方法都在线程中启动。其中一些方法预计会引发异常,这些异常必须在主程序中处理(= 不在方法本身中)。
问题:没有捕捉到异常并且解释(成功/失败)是错误的,因为所有线程都是“成功的”。
我认为可行的方法:一个try/except,其中的线程实际上是start()。
请注意,在 Traceback 中,两个答案都是 (...) was successful,好像 try 仅处理启动线程 (.start()) 的事实,而不是线程本身发生的事情。
import threading
class Checks:
@staticmethod
def isok():
print("OK")
@staticmethod
def isko():
raise Exception("KO")
# db will keep a map of method names in Check with the actual (executable) method
db = {}
# getting all the methods from Checks, without the built_in ones
for check in [k for k in dir(Checks) if not k.startswith('_')]:
# create a thread for the method
db[check] = threading.Thread(target=getattr(Checks, check))
try:
# start the thread
db[check].start()
except Exception:
print(f"{check} raised an exception")
else:
print(f"{check} was successful")
# wait for all the threads to be finished
for thread in db.keys():
db[thread].join()
# all the threads are finished at that point
print("all threads are done")
输出:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\yop\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 926, in _bootstrap_inner
self.run()
File "C:\Users\yop\AppData\Local\Programs\Python\Python37-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/yop/.PyCharm2019.2/config/scratches/scratch_6.py", line 11, in isko
raise Exception("KO")
Exception: KO
isko was successful
OK
isok was successful
all threads are done
(由于线程的原因,Traceback会与程序的实际输出混合,但顺序始终相同)
编辑:跟进评论我想再次强调异常将发生在方法中,但必须在主程序中捕获(= 不在方法本身中处理)。
在非线程方法中,这很容易:类似于上述代码中的try/exception 子句会在它们冒泡时捕获它们。
【问题讨论】:
-
您可以使用
logging记录线程中的错误。 -
或者你可以使用一些线程安全的数据结构来存储错误,然后在main中读取。
-
@JayVasant:由于方法的性质,正如我在问题中提到的,必须在主程序中捕获异常(它们发生的事实会在实际情况下触发进一步的操作)
-
追溯每一个功能
-
@SaisivaA:我不明白该怎么做? (你也许可以把它放在答案中?)
标签: python python-3.x multithreading