python只运行一次apschedule BlockingScheduler

python只运行一次apschedule BlockingScheduler,python,multithreading,apscheduler,Python,Multithreading,Apscheduler,我正在使用apscheduler在另一个线程中以10分钟的间隔安排特定任务。这可以很好地工作,我还可以在我在初始调度器和其他任务中启动的记录器中提取这些信息。我现在的问题是,当我尝试只执行一次调度程序,然后将其与应用程序一起终止时,由于某些原因,它没有发生,并且应用程序似乎仍在运行(等待某些内容),因此没有退出/终止。下面是我正在使用的代码片段: import os import sys import logging from datetime import datetime from subp

我正在使用apscheduler在另一个线程中以10分钟的间隔安排特定任务。这可以很好地工作,我还可以在我在初始调度器和其他任务中启动的记录器中提取这些信息。我现在的问题是,当我尝试只执行一次调度程序,然后将其与应用程序一起终止时,由于某些原因,它没有发生,并且应用程序似乎仍在运行(等待某些内容),因此没有退出/终止。下面是我正在使用的代码片段:

import os
import sys
import logging
from datetime import datetime
from subprocess import Popen, PIPE
from apscheduler.schedulers.blocking import BlockingScheduler

import recorder
import threading


def run_daily_sessions(thelogger):
    thelogger.info("[{}] - Trigger triggered".format(datetime.now()))
    thelogger.info("[{}] - Going to run daily scheduler script".format(datetime.now()))
    r = recorder.Recorder() # start recorder on another thread
    r.start()

    thelogger.info("[{}] - Ran daily scheduler script".format(datetime.now()))    

def main():
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)
    handler = logging.FileHandler('scheduler.log')
    handler.setLevel(logging.DEBUG)
    logger.addHandler(handler)
    logger.info("[{}] - scheduler.py was run".format(datetime.now()))

    sched = BlockingScheduler()
    logger.info("[{}] - blocking scheduler was created".format(datetime.now()))
    sched.add_job(run_daily_sessions, args=[logger])
    # sched.add_job(run_daily_sessions, 'interval', minutes=10, args=[logger])
    logger.info("[{}] - everyday task added, going to start the scheduler".format(datetime.now()))
    sched.start()
    # sched.shutdown()
    #logging.root.removeHandler(handler)
    return 0


if __name__ == '__main__':
    STATUS = main()
    print("terminating application!!!")
    sys.exit(STATUS)
我已尝试将
max_instances=1
作为参数添加到
sched.add_job()
或添加
sched.shutdown()
,但两者都不起作用。然后我认为这可能是由于logger实例,所以我尝试删除处理程序,但也没有成功。因此,我试图理解,既然调度程序已完成其任务或任何子任务,为什么应用程序从未达到打印(“终止应用程序!!!”)和退出。我的线程经验是有限的,但我认为我已经按照网络上的一些例子正确地做了一些事情,因此有没有想法我可能做错了什么或遗漏了什么


解决方案:

多亏了@Alex Grönholm和他的反馈,他使用了一个工作函数,成功了。代码片段:

def terminate_scheduler(thesched, thelogger, should_exit=False):
    if should_exit:
        thelogger.info('[{}] - finished scheduler... going to exit'.format(datetime.now()))
        thesched.shutdown(wait=False)

def main():
...
...
...
    sched.add_job(run_daily_sessions, args=[logger])
    sched.add_job(terminate_scheduler, args=[sched, logger, {"should_exit": True}]) # add job function for terminating scheduler
...
...
    sched.start()
...
...
    return 0

if __name__ == '__main__':
    STATUS = main()
    print("terminating application!!!")
    sys.exit(STATUS)

您似乎认为,一旦调度程序没有剩余的作业,它就应该自行隐式终止。这是一个错误的假设。如果要关闭计划程序,必须从另一个线程显式关闭。

但是调用
sched.shutdown()
不应在所有作业完成后终止计划程序。
shutdown()
方法将关闭计划程序,无论计划是否完成。但是我没有看到您在代码段中调用此方法。它位于
sched.start()
注释的下面。正如我所说,我已经使用了它,但仍然不允许我退出应用程序。如果你将它放在
sched.start()
之后,它将只在计划程序关闭后调用,这毫无意义。因此,您需要从作业函数或事件侦听器调用它。我明白了,使用作业函数确实做到了,谢谢。我还用可能的解决方案更新了我的问题。正如我所说,我对这门学科还不熟悉,所以一开始就没法理解。