Если я создаю поток перед запуском сервера флеш-памяти, этот поток не прерывается, если сервер фляги перезапускается («Перезапуск с помощью windowsapi reloader»). Однако если я затем отредактирую файлы, последующие перезапуски уничтожат все потоки, кроме начавшихся оригинальных.
Примечание. Я проверял это только в Windows. Запуск Windows 10, Python 3.7.3. Побежал из cmd.exe.
Причина этого вопроса в том, что я использую флешку, чтобы дать http доступ к многочисленным потокам, которые работают не в фляге. Я в основном конвертирую приложение Delphi 5 в Python.
Полный пример моей проблемы ниже. Это будет запускаться noisy_thread()
дважды, потому что флешка мгновенно перезапускается при запуске (меня не беспокоит, что она перезагружается, просто она не очищает первый поток при перезапуске):
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 не убито, когда должно быть ИМО.
Я бы хотел просто запустить потоки на фабрике create_app () для моего приложения-колбы и не должен определять, запущен ли я в производстве или разработке (точнее, определить, включен ли перегрузчик).
Это хак, который я хочу избежать:
if app.config['ENV'] == 'production' or os.environ.get("WERKZEUG_RUN_MAIN") is not None:
<start long running thread here>