Flask-SocketIO eventlet无法切换到不同的线程

时间:2016-04-03 12:16:51

标签: python multithreading eventlet flask-socketio

我目前正在开发的项目使用Flask-SocketIO在我的Raspberry Pi和连接到它所服务的网站的客户之间进行通信。但是,一旦我设置了一个或多个额外的线程,就会发生错误。我使用猴子补丁来允许后台线程(这是有效的)。但当我启动另一个来处理特定事件时,程序崩溃了。这些是目前的核心文件:

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")

other_module在执行run方法时会经常向所有客户端发出事件(可能会运行几分钟,但经常睡觉),所以我认为它与此有关。单独定义apps模块以避免此类循环依赖性。这是other_module执行run方法时遇到的错误,仅此而已:

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

编辑:每当我尝试在不同的线程中使用我的PiCamera时,就会出现错误。我已经尝试使用eventlet.import_patched("picamera")安全地导入它,但没有任何成功。我应该回到async_mode="threading"吗?

1 个答案:

答案 0 :(得分:0)

隔离问题。如果它没有PiCamera,那么现在你最好的选择是:

  • 异步模式=线程
  • PiCamera在单独的过程中并通过套接字进行通信