Home > front end >  Python threading in flask webapp
Python threading in flask webapp

Time:02-16

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)
  • Related