I've been trying threads recently in my webapp, and I've come across an issue that I cannot seem to solve.
The issue is that I have an index page, and every time the user enters that page, a new thread is being started which checks for changes in my database in a while loop, although I only want one thread to be on at that moment. Is there a way to "kill" a thread when the index page is accessed the second time and then start a new one?
I did try to use is_alive()
to check if a thread is already running, but had no success since all the time they're different.
Code example below:
@app.route("/")
def index():
@copy_current_request_context
def check_for_updates():
while True:
...... # Query for information
if something_changed:
socketio.emit('new_notifications', {'data': new_data})
if index_opened_again:
break
sleep(5)
index_thread = threading.Thread(target=check_for_updates, daemon=True)
index_thread.start()
return render_template("index.html")
CodePudding user response:
I user the below code to kill threads when I am existing a server , My suggestion is to kill all active threadss before opening a new one
for id, thread in threading._active.items():
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, ctypes.py_object(SystemExit))
CodePudding user response:
In my example I use a global variable in combination with a lock. It's certainly not optimal, but you can check if a thread is already running.
If you're using flask-socketio anyway, I recommend you take a look at start_background_task
. The functionality is compatible with that of a standard thread.
from threading import Lock
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
app.secret_key = 'your secret here'
sio = SocketIO(app)
thread = None
thread_lock = Lock()
def background_task():
while True:
# ...
sleep(5)
@app.route('/')
def index():
global thread
with thread_lock:
if thread is None:
thread = sio.start_background_task(background_task)
return render_template('index.html')
if __name__ == '__main__':
sio.run(app)