2016-04-03 16 views
1

Das Projekt, an dem ich gerade arbeite, verwendet Flask-SocketIO zur Kommunikation zwischen meinem Raspberry Pi und Clients, die eine Verbindung zu der Website herstellen, die es bedient. Ein Fehler tritt jedoch auf, sobald ich einen oder mehrere zusätzliche Threads eingerichtet habe. Ich habe einen Affen-Patch verwendet, um einen Hintergrund-Thread zu erlauben (das funktioniert). Aber wenn ich ein anderes starte, um ein bestimmtes Ereignis zu behandeln, stürzt das Programm ab. Dies sind die Kerndateien zur Zeit:Flask-SocketIO Eventlet kann nicht zu einem anderen Thread wechseln

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

Die other_module häufig Ereignisse für alle Kunden bei der Ausführung seiner run Methode emittieren (die Minuten laufen kann, aber schläft häufig), also nehme ich an, dass es etwas damit zu tun hat. Das apps Modul ist separat definiert, um solche ansonsten zyklischen Abhängigkeiten zu vermeiden. Das ist der Fehler, den ich bekommen, während other_module seine run Methode ausgeführt wird, nicht mehr und nicht weniger:

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: Es sieht aus wie der Fehler tritt auf, wenn ich versuche, meine PiCamera in einem anderen Thread zu verwenden. Ich habe bereits versucht, es sicher mit eventlet.import_patched("picamera") zu importieren, aber ohne Erfolg. Sollte ich auf async_mode="threading" zurückgreifen?

+0

Try Affe Patchen eventlet in Ihrer Hauptdatei kommunizieren vor allem Ihre Importe. – Miguel

+0

Ich habe das versucht, aber es hat nicht funktioniert. Ich denke, es könnte etwas damit zu tun haben, dass das 'andere Modul' einen anderen Thread erzeugt (für eine' PiCamera', die während ihrer 'run'-Methode fortlaufend aufnimmt). Ich habe einige andere Ereignisse, die einen neuen Thread einrichten, und diese funktionieren gut. – Y4sper

+0

Ich denke, Sie sollten sicherstellen, dass das Affepatching in der gesamten Anwendung funktioniert. Mein Verständnis ist, dass dieser Fehler, den Sie erhalten, beim Mischen von regulären und grünen Threads auftritt. – Miguel

Antwort

0

Isolieren Sie das Problem. Wenn es ohne PiCamera funktioniert, dann jetzt die beste Wahl ist entweder:

  • Asynchron-mode =
  • PiCamera in separaten Prozess Einfädeln und über Sockets
+0

Ich werde es versuchen, aber ich denke, der mögliche Gewinn in der Leistung wird seine erhöhte Komplexität nicht schlagen. Ich kann einfach auf 'async-mode =" threading "zurückgreifen und damit einfach umgehen. – Y4sper

+0

Threading ist Leistung. Separater Prozess ist eine Problemumgehung für Probleme. – temoto

+0

Ich meinte den Gewinn in der Leistung in der Lage zu sein, 'eventlet' weiter zu verwenden, aber es scheint, als würde ich wieder in den' async-mode = "threading" fallen, was am besten für mich funktioniert. – Y4sper