使用 Flask 运行计划时的问题

Posted

技术标签:

【中文标题】使用 Flask 运行计划时的问题【英文标题】:Issue when running schedule with Flask 【发布时间】:2015-01-24 19:04:36 【问题描述】:

我需要在我的 Flask 应用程序上定期运行某个任务。我决定使用一个简单的库 - Schedule (https://github.com/dbader/schedule) 来执行此操作。我在与主应用程序线程不同的线程上运行任务调度程序。这是相关的代码sn-p。

import schedule
import time

from flask import Flask, request
from threading import Thread

app = Flask(__name__)

start_time = time.time()

def run_every_10_seconds():
    print("Running periodic task!")
    print "Elapsed time: " + str(time.time() - start_time)

def run_schedule():
    while 1:
        schedule.run_pending()
        time.sleep(1)   

@app.route('/', methods=['GET'])
def index():
    return '<html>test</html>'

if __name__ == '__main__':
    schedule.every(10).seconds.do(run_every_10_seconds)
    t = Thread(target=run_schedule)
    t.start()
    print "Start time: " + str(start_time)
    app.run(debug=True, host='0.0.0.0', port=5000)

当我运行它时,我想要“运行定期任务!”每 10 秒打印一次。然而,这是我得到的输出。

 * Running on http://0.0.0.0:5000/
 * Restarting with reloader
Start time: 1417002869.99
Running periodic task!
Elapsed time: 10.0128278732
Running periodic task!
Elapsed time: 10.0126948357
Running periodic task!
Elapsed time: 20.0249710083
Running periodic task!
Elapsed time: 20.0247309208
Running periodic task!
Elapsed time: 30.0371530056
Running periodic task!
Elapsed time: 30.0369319916

显然,出于某种原因,该任务似乎每 10 秒执行两次,而不是一次。但是,如果我只运行任务调度程序而不是与 Flask 一起运行(通过简单地注释 app.run() 行),它会正常运行。

Start time: 1417003801.52
Running periodic task!
Elapsed time: 10.0126750469
Running periodic task!
Elapsed time: 20.0246500969
Running periodic task!
Elapsed time: 30.0366458893

这背后的原因可能是什么?运行多个线程时任务排队的方式有问题吗?它仍然没有解释为什么在一次只应该安排一个任务的时候安排两个任务。

【问题讨论】:

【参考方案1】:

当你用reloader运行开发服务器时(debug=True的默认值),模块执行两次,导致t的两个实例。您可以通过添加print(id(t)) 来验证这一点。

解决此问题的最简单方法是将use_reloader=False 传递给app.run。您可以查看this answer 以获得允许您使用重新加载器的替代解决方案。

【讨论】:

以上是关于使用 Flask 运行计划时的问题的主要内容,如果未能解决你的问题,请参考以下文章

Flask 框架中 SQLAlchemy 使用时的乱码问题

Flask python setup:安装时的oauthlib版本问题

Flask传递中文URL时的问题

技巧 | 写 Flask 应用时的一些优雅技巧

0_创建Flask 对象时的初始化参数

Flask 启动时的源码简析