How to return to the main thread from a callback called on another thread

吃可爱长大的小学妹 提交于 2019-12-13 02:17:50

问题


I'd like to execute my code from a background callback into the main thread. For some reasons I didn't found simple examples to perform that.

I found example with Queue and pooling, this is clearly not what I want. I just want to join the main thread in order to execute my function.

Here is some simple code:

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.

** Edit **

Here is my problem: main file:

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)

from another file, I've got a decorator who deal with the socket event:

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

And here is the problem: I have some events triggered by an hardware button, which trigger a callback who call sio "test" event. But because the events are not triggered into the same thread, this cause me some trouble:

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

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

the test method decorator is called: but when the emit is done not on the main thread, this stop working.

as long as the socket call are done from the Mainthread, it is ok. but when one call is done on DummyThread, this not working anymore.

I test on a client device with socket.io implementation. As long as the "emit" are done on the mainthread, it works, but when I perform on another thread (like with a button who trigger the callback, it stop working)

That's why I'd love to perform


回答1:


You can easily pass values between threads by using a Queue instance.

This simple demonstration script explains the concept. You can abort the script using 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()


来源:https://stackoverflow.com/questions/35550501/how-to-return-to-the-main-thread-from-a-callback-called-on-another-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!