Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute Python function in Main thread from call in Dummy thread

Tags:

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?

like image 911
Jim C Avatar asked Sep 24 '13 18:09

Jim C


People also ask

How do you execute functions in a separate new thread with the module thread?

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.

How do I run a Python code from another thread?

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.

Can a thread call a function?

Yes, but you should take care that the function does not alter state in such a way that other threads would be impacted negatively.

Which Python function can be called to run a thread?

In Python, we can create and run threads using the threading module.


1 Answers

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

like image 105
Claudiu Avatar answered Sep 28 '22 08:09

Claudiu