简体   繁体   中英

Flask-SocketIO eventlet cannot switch to a different thread

The project I'm currently working on uses Flask-SocketIO to communicate between my Raspberry Pi and clients connecting to the website it serves. However, an error occurs once I set up one or more extra threads. I used a monkey patch to allow a background thread (this works). But when I start up another one to handle a specific event, the program crashes. These are the core files currently:

apps.py

import eventlet
eventlet.monkey_patch()

from flask import Flask
from flask_socketio import SocketIO

app = Flask(__name__)
sio = SocketIO(app, async_mode="eventlet")

main.py

import apps
import other_module
import another_module    

from threading import Thread

from flask_socketio import emit

@apps.sio.on("problematic")
def this_is_problematic(data):
    Thread(target=other_module.run).start()

def updates():
    while True:
        apps.sio.emit("data", another_module.data())
        time.sleep(.3)

if __name__ == "__main__":
    Thread(target=updates).start()
    apps.sio.run(apps.app, host="0.0.0.0")

The other_module will frequently emit events to all clients during the execution of its run method (which may run for minutes, but sleeps frequently), so I assume it has something to do with that. The apps module is defined seperately to avoid such otherwise cyclic dependencies. This is the error I get while other_module is executing its run method, nothing more and nothing less:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/eventlet/hubs/hub.py", line 457, in fire_timers
  File "/usr/local/lib/python2.7/dist-packages/eventlet/hubs/timer.py", line 58, in __call__
    cb(*args, **kw)
  File "/usr/local/lib/python2.7/dist-packages/eventlet/semaphore.py", line 145, in _do_acquire
    waiter.switch()
error: cannot switch to a different thread

Edit: It looks like the error occurs whenever I try to use my PiCamera in a different thread. I already tried importing it safely using eventlet.import_patched("picamera") , but without any success. Should I fall back to async_mode="threading" ?

Isolate the problem. If it works without PiCamera, then right now your best option is either:

  • async-mode=threading
  • PiCamera in separate process and communicate via sockets

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM