【问题标题】:Python APSCheduler Exception managementPython APSCheduler 异常管理
【发布时间】:2016-01-13 17:57:50
【问题描述】:

我在脚本中使用模块APScheduler,我使用BlockingScheduler。我有一些周期性的工作。如果这项工作raiseException,无论我在expect 它在try 中还是让它传播,我的线程都不会返回。然后我到达max_instance,没有更多的工作被执行。

在使用BlockingScheduler时,我应该如何在线程中管理Execptions

这里我的 MWE 说明了我的问题:

from apscheduler.schedulers.blocking import BlockingScheduler
import threading

class x:

    def __init__(self):
        self._lock = threading.Lock()

    def __enter__(self):
        print("ENTER")
        self._lock.acquire()
        print("LOCK")
        raise Exception("ERROR")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("EXIT")
        self._lock.release()
        print("UNLOCK")

a = x()

def test():
    print("TEST")
    with a:
        print("WITH")

pollingScheduler = BlockingScheduler()
pollingScheduler.add_job(test, 'interval', seconds=1, max_instances=1)
pollingScheduler.start()

我希望在引发异常时必须调用 __exit__() 方法,即使是 __enter__() 引发异常也是如此。在睾丸之后,我看到__exit__() 没有被调用就是这样的场景。因此会导致死锁和线程卡住。

我应该如何解决这个问题? 看起来__enter__() 不能引发异常。对吗?

【问题讨论】:

    标签: python python-3.x exception apscheduler


    【解决方案1】:

    这里的问题是__exit__ 只有在__enter__ 成功完成时才会被调用。由于您在__enter__ 中引发异常,因此锁处于已获取状态,因此在尝试获取锁时后续运行作业将挂起。如果您希望 __enter__ 中出现异常,请将其包装在 try...except 块中,如果引发异常,该块将释放锁定。

    【讨论】:

    • 是的,我在构建 MWE 时发现了这一点。谢谢你的回答。声明行为我没有意识到这一点。
    • 我已经通过这种方式解决了这个问题,我将敏感代码嵌入到 try...except 块中,然后如果 __enter__ 出现问题,我会调用 __exit__ 并重新提出 exception 让他们传播。这是一个好习惯吗?
    • __enter__ 呼叫__exit__?我不会那样做。
    • 你能说得更清楚些吗?只有当我遇到无法恢复的错误时,我才会调用__exit__。因此我必须释放我已经打开的资源,这就是__exit__ 的目的。对不对。
    • 或者我应该创建一些我在__enter____exit__ 中调用的其他函数。无论如何,您能否解释一下为什么在__enter__ 崩溃时不调用__exit__ 是一个好习惯。
    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多