Get return value from thread python
I stole kindall's answer and cleaned it up just a little bit. Show
The key part is adding *args and **kwargs to join() in order to handle the timeout
UPDATED ANSWER BELOW This is my most popularly upvoted answer, so I decided to update with code that will run on both py2 and py3. Additionally, I see many answers to this question that show a lack of comprehension regarding Thread.join(). Some completely fail to handle the ThreadWithReturn class that works with py2 and py3:
Some sample tests are shown below:
Can you identify the corner-case that we may possibly encounter with TEST 4? The problem is that we expect giveMe() to return None (see TEST 2), but we also expect join() to return None if it times out.
(1) that's what giveMe() returned, or (2) join() timed out This example is trivial since we know that giveMe() will always return None. But in real-world instance (where the target may legitimately return None or something else) we'd want to explicitly check for what happened. Below is how to address this corner-case: Last Updated on September 9, 2022 You can return values from a thread via instance variables on the threading.Thread class or via global variables. In this tutorial you will discover how to return values from a thread. Learn threading systematically with this 7-day jump-start. Let’s get started. Table of Contents
Need to Return Values From a ThreadA thread is a thread of execution in a computer program. Every Python program has at least one thread of execution called the main thread. Both processes and threads are created and managed by the underlying operating system. Sometimes we may need to create additional threads in our program in order to execute code concurrently. Python provides the ability to create and manage new threads via the threading module and the threading.Thread class. You can learn more about Python threads in the guude:
When using new threads, we may need to return a value from the thread to another thread, such as the main thread. This may be for many reasons, such as:
How can we return values from a thread in Python? How to Return Values From a ThreadA thread cannot return values directly. The start() method on a thread calls the run() method of the thread that executes our code in a new thread of execution. The run() method in turn may call a target function, if configured. The start() method does not block, instead it returns immediately and does not return a value. The run method also does not return a value. We can join a new thread from the current thread and block until the new thread terminates, but the join() method also does not return a value. Instead, we must return values from a thread indirectly. There are two main ways to return values from a thread, they are:
The preferred approach is to extend the threading.Thread class and store return data as instance variables. This involves defining a new class that extends the threading.Thread and defines a constructor that calls the parent constructor. The run() method can be defined that executes the custom code in a new thread and stores data as instance variables.
An alternate approach is to store data from the thread in a global variable. All threads will be able to access global variables. This may be a preferred approach if you already have a function executing in a new thread and need to get data out of the thread. The scope of the global variable can be made explicit and data can be stored directly.
The danger of both approaches is that there could be a race condition between the new thread storing data in an instance variable or global variable and one or more other threads reading that data. The solution could be to protect the data with a threading.Lock, to use a threading.Event to flag that the return data is available, or to use a threading.Condition to notify threads that the data is ready. A simpler approach is to simply wait for the new thread to terminate. Now that we know how to return values from a thread, let’s look at some worked examples. How well do you know threading? Example of Returning a Value From a ThreadWe can explore how to simulate returning a single value from a thread via an instance variable. In this example we will define a new class that extends the threading.Thread class, define the instance variable in the constructor and set it to None, then override the run() function with custom code and set the instance variable. The main thread will then access the return value. First, let’s define the new class that extends the Threading.Thread class and defines a constructor that calls the parent constructor. In the constructor we will also define a new public property named “value” and set it to the value None.
Next, we can override the run() method on threading.Thread to execute some custom code. In this case, we will block for a moment, then store data on the “value” instance variable.
Tying this together, the complete new class is listed below.
Next, the main thread can create an instance of our new thread and then call the start() function to start executing it.
The main thread will then join this new thread and block until it has terminated.
Once the new thread has terminated, the main thread knows that the variable was set. We can access it directly and report the value.
Tying this together, the complete example of returning a value from a thread is listed below.
Running the example first creates the new thread instance and starts the execution. The main thread blocks until the new thread has completed, then accesses the instance variable and reports its value. This simulates a simple single return value from the new thread. Next, let’s look at how we might return multiple values from a thread. Example of Returning Multiple Values From a ThreadWe can explore simulating the return of multiple values from the new thread. Using the “instance variables” technique, this involves simply defining and using multiple instance variables on our custom threading.Thread class. We can update the above example to simulate returning multiple values. First, we will follow the good practice of defining our properties in the constructor of the class and setting default values. In this case it will have three return values: “value1“, “value2“, and “value3“.
Next, we can update the overridden run() method to set values in each instance variable.
Finally, we can update the main thread to access the instance variables like return values from the new thread.
Tying this together, the complete example of returning multiple values from a thread is listed below.
Running the example creates and runs the new thread. The main thread blocks until the new thread has terminated and we know that the instance variables have been assigned data. Finally, the main thread accesses the instance variables and reports their values, simulating multiple return values from the new thread.
Next, let’s look at how we might return values from a thread via a global variable. Example of Returning Values Via Global VariablesWe can explore how we might use global variables to simulate returning values from a new thread. This approach might be preferred if we already have a function that we are running in a new thread. First, we can define a new target task function to run in a new thread. The function will block for a moment, then declare the scope of a global variable and assign it a value.
The main thread will define the global variable and set a default value.
We can then create a new threading.Thread instance and have it call our new task() function by specifying it in the “target” variable of the constructor.
The main thread can then start the new thread and join it, blocking until the new thread has terminated.
Finally, once we know the new thread has terminated and that the global variable has been assigned by the new thread, we can report its value.
Tying this together, the complete example of returning values from another thread via global variables is listed below.
Running the example first creates the new thread and starts it, executing our custom target function. The new thread then stores data against the global variable, being sure to explicitly specify the scope to avoid confusion in reading the code and possible bugs in the future. THe main thread blocks until the new thread terminates then reports the simulated return value stored in the global variable. Further ReadingThis section provides additional resources that you may find helpful.
TakeawaysYou now know how to return values from a thread in Python. Do you have any questions? Photo by Harley-Davidson on Unsplash Can a thread return a value Python?A thread cannot return values directly. The start() method on a thread calls the run() method of the thread that executes our code in a new thread of execution. The run() method in turn may call a target function, if configured.
How do I get the return value of a threaded function?pool import ThreadPool pool = ThreadPool(processes=1) async_result = pool. apply_async(foo, ('world', 'foo')) # tuple of args for foo # do some other stuff in the main process return_val = async_result. get() # get the return value from your function.
How do you return a value from thread run method in Java?The thread that needs to return the value uses the Callable interface to implement the call method; Before getting the future object, you can use the isDone() method to check whether the future is complete. After that, you can call the get() method to get the value of the future.
Which is better multiprocessing or multithreading in Python?Multiprocessing is a easier to just drop in than threading but has a higher memory overhead. If your code is CPU bound, multiprocessing is most likely going to be the better choice—especially if the target machine has multiple cores or CPUs.
|