如何从另一个线程上调用的回调返回主线程

时间:2016-02-22 09:53:42

标签: python multithreading eventlet

我想将后台回调中的代码执行到主线程中。由于某些原因,我没有找到执行该操作的简单示例。

我找到了Queue和pooling的例子,这显然不是我想要的。我只想加入主线程以执行我的功能。

以下是一些简单的代码:

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)

从另一个文件中,我有一个处理socket事件的装饰者:

@sio.on('test')
def test(sid, data):
    print threading.currentThread()
    sio.emit('event triggered')

问题在于:我有一些由硬件按钮触发的事件,它触发了一个调用sio“test”事件的回调。但是因为事件没有被触发到同一个线程中,这会给我带来一些麻烦:

# async call !
def event_cb(num):
    sio.emit('test')

GPIO.add_event_detect(btNumber, GPIO.RISING, event_cb)

调用测试方法装饰器: 但是当不在主线程上完成发射时,这将停止工作。

只要套接字调用是从 Mainthread 完成的,就可以了。 但是当在 DummyThread 上进行一次通话时,此功能不再有效。

我在使用socket.io实现的客户端设备上进行测试。只要在mainthread上完成“emit”就可以了,但是当我在另一个线程上执行时(比如触发回调的按钮,它就会停止工作)

这就是我喜欢表演的原因

1 个答案:

答案 0 :(得分:2)

您可以使用Queue实例轻松地在线程之间传递值。

这个简单的演示脚本解释了这个概念。您可以使用 Ctrl - C 中止脚本。

#!/usr/bin/env python
import Queue
import random
import threading
import time

def main_thread():
    """Our main loop in the main thread.

    It receives the values via a Queue instance which it passes on to the
    other threads on thread start-up.
    """
    queue = Queue.Queue()

    thread = threading.Thread(target=run_in_other_thread,
                              args=(queue,))
    thread.daemon = True  # so you can quit the demo program easily :)
    thread.start()

    while True:
         val = queue.get()
         print "from main-thread", val

def run_in_other_thread(queue):
    """Our worker thread.

    It passes it's generated values on the the main-thread by just
    putting them into the `Queue` instance it got on start-up.
    """
    while True:
         queue.put(random.random())
         time.sleep(1)

if __name__ == '__main__':
    main_thread()