miguelgrinberg / Flask-SocketIO

Socket.IO integration for Flask applications.
MIT License
5.31k stars 888 forks source link

Cannot start multiple threads #1990

Closed makaveli10 closed 1 year ago

makaveli10 commented 1 year ago

I cannot start the second thread with the first thread having an infinite loop. I want to know if socketio runs threads in the background? If so, why it waits for the first thread to finish up?

Below is my code:

async_mode = None

if async_mode is None:
    try:
        import eventlet
        async_mode = 'eventlet'
    except ImportError:
        print('Sm')
        pass

    if async_mode is None:
        try:
            from gevent import monkey
            async_mode = 'gevent'
        except ImportError:
            pass

    if async_mode is None:
        async_mode = 'threading'

    print('async_mode is ' + async_mode)

if async_mode == 'eventlet':
    import eventlet
    eventlet.monkey_patch()
elif async_mode == 'gevent':
    from gevent import monkey
    monkey.patch_all()

# End patching

# Do imports 
from threading import Thread

from flask import Flask, render_template, request, current_app
from flask_socketio import SocketIO

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*", async_mode=async_mode)

# Set tread defaults
thread = None
ping_thread = None
run_threads = True

@socketio.on('connect')
def connected():
    print("here")
    global run_threads
    global thread
    global ping_thread

    run_threads = True

    if thread is None or not thread.isAlive():
        # Set up the long running loop to listen for any changes from the Sonos
        thread = Thread(target=long_running)
        thread.daemon = True
        thread.start()
    if ping_thread is None or not ping_thread.isAlive():
        ping_thread = Thread(target=ping_test)
        ping_thread.daemon = True
        ping_thread.start()

def long_running():
    # Using run_threads so we can terminate when we lose connection.
    global run_threads, thread
    i = 0
    while run_threads:
        # Do stuff here.
        print("hello", i)
        i += 1

def ping_test():
    """
    Test for internet connectivity.
    Will spawn as a seperate thread.
    """
    global run_threads
    while run_threads:
        print("hello2")
        xx

if __name__ == '__main__':
    # use_reloader=False is needed otherwise we will spawn extra threads.
    socketio.run(app, use_reloader=False, debug=True, port=9090, host='127.0.0.1')
bluthen commented 1 year ago

You monkey patched threads, so they are async. So it all runs on one thread. In your infinite loop you need sleep (depending what else is in the threaded function) for any of the other "async threads" to do anything.

If you need true threads, I'd use another python process for the threaded stuff.

https://eventlet.net/doc/modules/greenthread.html#eventlet.greenthread.sleep