[英]How to create global error handler in a multi-threaded python applcation
I am developing a multi-threaded application in python. 我正在用python开发多线程应用程序。 I have following scenario. 我有以下情况。
Now for such a setup I want a common error handler which senses failure of any thread, any exception and decides what to do. 现在,对于这样的设置,我需要一个通用的错误处理程序,该处理程序可以检测任何线程,任何异常的失败并确定要执行的操作。 For eg if I press ctrl+c after I start my application, main thread dies but producer, consumer threads continue to run. 例如,如果我在启动应用程序后按ctrl + c,则主线程死亡,但生产者,使用者线程继续运行。 I would like that once ctrl+c is pressed entire application should shut down. 我希望一旦按下ctrl + c,就应该关闭整个应用程序。 Similarly if some DB error occurs in data source module, then producer thread should get notified of that. 同样,如果在数据源模块中发生一些DB错误,则生产者线程应该得到通知。
This is what I have done so far: 到目前为止,这是我所做的:
I have created a class ThreadManager, it's object is passed to all threads. 我创建了一个ThreadManager类,它的对象被传递给所有线程。 I have written an error handler method and passed it to sys.excepthook
. 我编写了一个错误处理程序方法,并将其传递给sys.excepthook
。 This handler should catch exceptions, error and then it should call methods of ThreadManager class to control the running threads. 该处理程序应捕获异常,错误,然后应调用ThreadManager类的方法来控制正在运行的线程。 Here is snippet: 这是代码段:
class Producer(threading.Thread):
....
def produce():
data = dataSource.getData()
class DataSource:
....
def getData():
raise Exception("critical")
def customHandler(exceptionType, value, stackTrace):
print "In custom handler"
sys.excepthook = customHandler
Now when a thread of producer class calls getData() of DataSource class, exception is thrown. 现在,当生产者类的线程调用DataSource类的getData()时,将引发异常。 But this exception is never caught by my customHandler method. 但是我的customHandler方法从未捕获过此异常。
What am I missing? 我想念什么? Also in such scenario what other strategy can I apply? 同样在这种情况下,我还可以采用什么其他策略? Please help. 请帮忙。 Thank you for having enough patience to read all this :) 感谢您有足够的耐心阅读所有这些内容:)
What you need is a decorator. 您需要的是一个装饰器。 In essence you are modifying your original function and putting in inside a try-except: 本质上,您正在修改原始功能,并放入try-except中:
def exception_decorator(func):
def _function(*args):
try:
result = func(*args)
except:
print('*** ESC default handler ***')
os._exit(1)
return result
return _function
If your thread function is called myfunc, then you add the following line above your function definition 如果您的线程函数称为myfunc,则在函数定义上方添加以下行
@exception_decorator
def myfunc():
pass;
Can't you just catch "KeyboardInterrupt" when pressing Ctrl+C and do: 您不能仅在按Ctrl + C时捕获“ KeyboardInterrupt”并执行以下操作:
for thread in threading.enumerate():
thread._Thread__stop()
thread._Thread__delete()
while len(threading.enumerate()) > 1:
time.sleep(1)
os._exit(0)
and have a flag in each threaded class which is self.alive you could theoretically call thread.alive = False and have it stop gracefully? 并在每个线程类中都有一个self.alive标志,从理论上讲,您可以调用thread.alive = False并使其正常停止吗?
for thread in threading.enumerate():
thread.alive = False
time.sleep(5) # Grace period
thread._Thread__stop()
thread._Thread__delete()
while len(threading.enumerate()) > 1:
time.sleep(1)
os._exit(0)
example: 例:
import os
from threading import *
from time import sleep
class worker(Thread):
def __init__(self):
self.alive = True
Thread.__init__(self)
self.start()
def run(self):
while self.alive:
sleep(0.1)
runner = worker()
try:
raw_input('Press ctrl+c!')
except:
pass
for thread in enumerate():
thread.alive = False
sleep(1)
try:
thread._Thread__stop()
thread._Thread__delete()
except:
pass
# There will always be 1 thread alive and that's the __main__ thread.
while len(enumerate()) > 1:
sleep(1)
os._exit(0)
Try going about it by changing the internal system exception handler? 尝试通过更改内部系统异常处理程序来解决此问题?
import sys
origExcepthook = sys.excepthook
def uberexcept(exctype, value, traceback):
if exctype == KeyboardInterrupt:
print "Gracefully shutting down all the threads"
# enumerate() thingie here.
else:
origExcepthook(exctype, value, traceback)
sys.excepthook = uberexcept
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.