I have a Python script that handles aynchronous callbacks from .NET Remoting. These callbacks execute in a dummy (worker) thread. From inside my callback handler, I need to call a function I've defined in my script, but I need the function to execute in the main thread.
The Main thread is a remote client that sends commands to a server. Some of these commands result in asynchronous callbacks.
Basically, I need the equivalent of .NET's Invoke method. Is this possible?
First, we must create a new instance of the threading. Thread class and specify the function we wish to execute in a new thread via the “target” argument. The function executed in another thread may have arguments in which case they can be specified as a tuple and passed to the “args” argument of the threading.
Use the Python threading module to create a multi-threaded application. Use the Thread(function, args) to create a new thread. Call the start() method of the Thread class to start the thread. Call the join() method of the Thread class to wait for the thread to complete in the main thread.
Yes, but you should take care that the function does not alter state in such a way that other threads would be impacted negatively.
In Python, we can create and run threads using the threading module.
You want to use the Queue (now queue from python 3) class to set up a queue that your dummy threads populate with functions and that your main thread consumes.
import Queue #somewhere accessible to both: callback_queue = Queue.Queue() def from_dummy_thread(func_to_call_from_main_thread): callback_queue.put(func_to_call_from_main_thread) def from_main_thread_blocking(): callback = callback_queue.get() #blocks until an item is available callback() def from_main_thread_nonblocking(): while True: try: callback = callback_queue.get(False) #doesn't block except Queue.Empty: #raised when queue is empty break callback()
Demo:
import threading import time def print_num(dummyid, n): print "From %s: %d" % (dummyid, n) def dummy_run(dummyid): for i in xrange(5): from_dummy_thread(lambda: print_num(dummyid, i)) time.sleep(0.5) threading.Thread(target=dummy_run, args=("a",)).start() threading.Thread(target=dummy_run, args=("b",)).start() while True: from_main_thread_blocking()
Prints:
From a: 0 From b: 0 From a: 1 From b: 1 From b: 2 From a: 2 From b: 3 From a: 3 From b: 4 From a: 4
and then blocks forever
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With