Python:将异常从 paho (MQTT) 线程传播到主线程

问题描述 投票:0回答:1

我有一个 python 应用程序,它使用线程从 MQTT 代理接收主题,并监视 UART 上的消息。在 Raspberry Pi 上运行。

泛美卫生组织 MQTT 库的接口提供回调来处理接收消息,并且

loop_start()
显然启动了一个新线程然后返回。

我的问题是,我希望接收回调中可能出现的异常一直引发到应用程序的“顶部”,以便我可以干净地终止整个应用程序。

现在,泛美卫生组织线程中的异常会终止该线程,但其他线程仍保持活动状态,并且应用程序正在运行但无法运行。这很糟糕,我依靠 systemd 服务来重新启动崩溃的应用程序,这就是为什么我需要它真正崩溃。

我已经为 UART RX 线程完成了此操作:

class MyClassError(Exception):
    def __init__(self, message):
        self.message = f"{message}"
        super().__init__(self.message)


class MyClass()::
    # other stuff...
    def rx(self):
        try:
            while True:
                do_your_thing()
        except Exception as e:
            self.exc = MyClassError(f"An unexpected error occurred: {e}")
            return

    def run(self):
        self.rx_thread.start()
        self.rx_thread.join()
        if self.exc is not None:
            raise self.exc

,它有效,但有一个警告,它不会返回。但我可以在调用者线程中捕获异常。

还有其他方法可以实现类似的效果,例如回调代码中的

try
/
except
/
sys.exit(1)
,或者也许让主线程监视paho线程的状态......但感觉我应该能够在子线程中引发异常,并在父线程中捕获它们。

此外,我想捕获并引发任何 MQTT 代码中的任何异常,而不仅仅是特定的回调。但这是第 2 步。

如何将 paho 库(或其调用的回调)中发生的异常升级到主线程,以便它可以终止一切?

python multithreading exception paho
1个回答
0
投票

我当前的解决方案是通过这种方式在顶层捕获未捕获的异常:


def handle_exceptions(e):
    try:
        my_object.stop()
    except Exception as e:
        print(e)
    try:
        mqtt_manager.stop()
    except Exception as e:
        print(e)
    print(traceback.print_exception(e.exc_type, e.exc_value, e.exc_traceback))

threading.excepthook = handle_exceptions

MQTT 循环在此停止后需要几秒钟才能终止(我想知道为什么?循环是否仅在下一个事件时终止?),但整个应用程序最终终止。

© www.soinside.com 2019 - 2024. All rights reserved.