【发布时间】:2016-02-22 09:53:42
【问题描述】:
我想将我的代码从后台回调执行到主线程。由于某些原因,我没有找到执行该操作的简单示例。
我发现了队列和池的例子,这显然不是我想要的。我只想加入主线程以执行我的功能。
下面是一些简单的代码:
def my_callback:
# this callback is called from a third party and I don't have control on it.
# But because of this, the function must_be_executed_on_main_thread is
# executed on the background.
must_be_executed_on_main_thread()
def must_be_executed_on_main_thread:
# must be executed on the main thread.
** 编辑 **
这是我的问题: 主文件:
if __main__ == '__main__'
sio = socketio.Server()
app = Flask(__name__)
app = socketio.Middleware(sio, app)
# now the thread is blocking into the server pool
eventlet.wsgi.server(eventlet.listen('', 7000)), app)
从另一个文件中,我有一个处理套接字事件的装饰器:
@sio.on('test')
def test(sid, data):
print threading.currentThread()
sio.emit('event triggered')
这就是问题所在:我有一些由硬件按钮触发的事件,这些事件触发了调用 sio“测试”事件的回调。但是由于事件没有触发到同一个线程中,这给我带来了一些麻烦:
# async call !
def event_cb(num):
sio.emit('test')
GPIO.add_event_detect(btNumber, GPIO.RISING, event_cb)
测试方法装饰器被调用: 但是当发射不在主线程上时,它会停止工作。
只要从 主线程 完成套接字调用,就可以了。 但是当一个调用在 DummyThread 上完成时,这不再起作用了。
我在使用 socket.io 实现的客户端设备上进行测试。只要在主线程上完成“发射”,它就可以工作,但是当我在另一个线程上执行时(比如触发回调的按钮,它就会停止工作)
这就是我喜欢表演的原因
【问题讨论】:
-
“停止工作”并不是对问题的明确描述。如果您不希望
wsgi.server阻塞主线程,请执行eventlet.spawn(eventlet.wsgi.server, listen(...), app)。不要忘记定期调用eventlet.sleep(0)以确保 Eventlet 主循环有机会处理网络事件。另外,你可以试试monkey_patch(threading=True),这样就会有一个操作系统线程。还要注意button bounce(谷歌搜索)。使用按钮的正确方法是 Linux gpio-keys 或通过采样手动去抖动。 -
根据性能要求自己执行循环(而不是某些库在 C 中)可能可行,也可能不可行。不过,它肯定会起作用。 :)
标签: python multithreading eventlet