TAGS :Viewed: 20 - Published at: a few seconds ago

[ how to run a function called in a thread outside that thread in python ]

I want to know the possibility to run a function in main thread, where the calling function is in another thread.

Consider below example

from thread import start_new_thread

def add(num1,num2):

    res = num1 + num2
    display(res)

def display(ans):
    print ans

thrd = start_new_thread(add,(2,5))

here i am calling add() in a new thread. which in turns calls display() i.e., display is also running in same thread.

I want to know how to run display() outside that thread.

New code as per the answers below

If i am trying to accept input from user and print the result. Its asking for input only once but not repeatedly...

from threading import Thread # threading is better than the thread module from Queue import Queue

q = Queue() # use a queue to pass messages from the worker thread to the main thread

def add():
    num1=int(raw_input('Enter 1st num : '))
    num2=int(raw_input('Enter 2nd num : '))
    res = num1 + num2
    # send the function 'display', a tuple of arguments (res,)
    # and an empty dict of keyword arguments
    q.put((display, (res,), {}))

def display(ans):
    print ('Sum of both two num is : %d ' % ans)

thrd = Thread(target=add)
thrd.start()

while True:  # a lightweight "event loop"
#    ans = q.get()
#    display(ans)
#    q.task_done()
    f, args, kwargs = q.get()
    f(*args, **kwargs)
    q.task_done()

and when i run the code, the result is as below

Current Result

Enter 1st num : 5
Enter 2nd num : 6
Sum of both two num is : 11 

Required Result

Enter 1st num : 5
Enter 2nd num : 6
Sum of both two num is : 11 

Enter 1st num : 8
Enter 2nd num : 2
Sum of both two num is : 10

Enter 1st num : 15
Enter 2nd num : 3
Sum of both two num is : 18

where i need it to be asking for inputs after printing result every time, like below

Answer 1


Sounds like you want all calls to display to happen on the main thread. Something like this unsophisticated example, using a Queue to send messages to the main thread, should work:

from threading import Thread  # threading is better than the thread module
from Queue import Queue

q = Queue()  # use a queue to pass messages from the worker thread to the main thread

def add(num1,num2):
    res = num1 + num2
    q.put(res)  # send the answer to the main thread's queue

def display(ans):
    print ans

thrd = Thread(target=add, args=(2,5))
thrd.start()

while True:  # a lightweight "event loop"
    ans = q.get()
    display(ans)
    q.task_done()

A typical generalisation of this lightweight "messaging framework" is to program your worker threads to put arbitrary functions and arguments on q. This allows you to make the main thread dumber. The code that deals with q would then look like this:

def add(num1,num2):
    res = num1 + num2
    # send the function 'display', a tuple of arguments (res,)
    # and an empty dict of keyword arguments
    q.put((display, (res,), {}))

# snip

while True:
    # now the main thread doesn't care what function it's executing.
    # previously it assumed it was sending the message to display().
    f, args, kwargs = q.get()
    f(*args, **kwargs)
    q.task_done()

From here you can see how you can design a robust and decoupled multi-threaded application. You equip every worker thread object with an input Queue, and a global mediator thread is responsible for shuffling messages between threads.

Note the the Queue-based approach to multithreading assumes that none of the threads share any global objects. If they do, you'd also need to ensure all shared objects have associated locks (see the threading documentation). Of course, this is then prone to the difficult synchronisation errors that the Queue-based approach seeks to avoid. The moral of the story, even though it seems like hard work, is to keep shared state to a minimum.

Answer 2


Seems like you want to impement rendezvous or a barrier