flask执行“使用Windowsapi重新加载程序重新启动”时

时间:2019-05-27 05:26:46

标签: python multithreading flask reload

如果我在运行Flask服务器之前创建了一个线程,则在烧瓶服务器重新启动(“使用Windowsapi重新加载程序重新启动”)时,该线程不会被杀死。但是,如果我随后编辑文件,则随后的重新启动会杀死所有线程,但原始线程除外。

注意,我仅在Windows上对此进行了测试。运行Windows 10,python 3.7.3。从cmd.exe运行。

此问题的原因是,我正在使用flask来对许多与flask无关的线程进行http访问。我基本上是将delphi 5应用程序转换为python。

下面是我问题的完整示例。 noisy_thread()将运行两次,因为flask在启动时会立即重新启动(我不担心它会重新启动,只是重新启动时不会清理第一个线程):

import os
import sys
import time
from threading import Thread, active_count, current_thread, enumerate, Event
from flask import Flask

stopper = Event()

def noisy_thread():
    while not stopper.isSet():
        print(f"Still running... (current: {current_thread()}, active: {active_count()}")
        time.sleep(2)
    print(f'Stopping {current_thread()}')

t = Thread(target=noisy_thread, daemon=True)
t.start()
app = Flask(__name__)
app.run(debug=True, use_reloader=True)
print("Flask ended")
stopper.set()
Thread.join(t)
print("Finished")

以上内容的输出(我在保持“烧瓶结束”之前点击了ctrl-c):

(.venv) C:\so_eg>python 1.py
Still running... (current: <Thread(Thread-1, started daemon 19028)>, active: 2
 * Serving Flask app "1" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Restarting with windowsapi reloader
Still running... (current: <Thread(Thread-1, started daemon 8056)>, active: 2
 * Debugger is active!
 * Debugger PIN: 156-430-547
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Still running... (current: <Thread(Thread-1, started daemon 19028)>, active: 2
Still running... (current: <Thread(Thread-1, started daemon 8056)>, active: 7
Flask ended
Still running... (current: <Thread(Thread-1, started daemon 19028)>, active: 2
Stopping <Thread(Thread-1, started daemon 8056)>
Finished
Flask ended
Stopping <Thread(Thread-1, started daemon 19028)>
Finished

如果运行上述命令,然后编辑1.py,然后将打印行更改为以下内容:

        print(f"Still running..2. (current: {current_thread()}, active: {active_count()}")

您将看到原始线程保持活动状态,但是最初重启时创建的线程被杀死并替换。我也希望在第一次重新启动时也发生这种情况。

示例输出:

Still running... (current: <Thread(Thread-1, started daemon 18360)>, active: 2
 * Serving Flask app "1" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Restarting with windowsapi reloader
Still running... (current: <Thread(Thread-1, started daemon 8784)>, active: 2
 * Debugger is active!
 * Debugger PIN: 156-430-547
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Still running... (current: <Thread(Thread-1, started daemon 18360)>, active: 2
Still running... (current: <Thread(Thread-1, started daemon 8784)>, active: 7
 * Detected change in 'C:\\TestLab\\device-link-server\\1.py', reloading
 * Detected change in 'C:\\TestLab\\device-link-server\\1.py', reloading
Still running... (current: <Thread(Thread-1, started daemon 18360)>, active: 2
Still running... (current: <Thread(Thread-1, started daemon 8784)>, active: 7
 * Restarting with windowsapi reloader
Still running..2. (current: <Thread(Thread-1, started daemon 19984)>, active: 2
 * Debugger is active!
 * Debugger PIN: 156-430-547
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Still running... (current: <Thread(Thread-1, started daemon 18360)>, active: 2
Still running..2. (current: <Thread(Thread-1, started daemon 19984)>, active: 7
Still running... (current: <Thread(Thread-1, started daemon 18360)>, active: 2
Flask ended
Stopping <Thread(Thread-1, started daemon 19984)>
Finished
Flask ended
Stopping <Thread(Thread-1, started daemon 18360)>
Finished

您应该看到18360在应为IMO时并未被杀死。

我只想在我的flask应用程序的create_app()工厂中运行线程,而不必检测我是在生产环境中还是在开发中(更确切地说是检测是否启用了重新加载器)。

这是我要避免的黑客:

if app.config['ENV'] == 'production' or os.environ.get("WERKZEUG_RUN_MAIN") is not None:
    <start long running thread here>

0 个答案:

没有答案