如果我在运行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>