I have a very simple threading example using Python 3.4.2. In this example I am creating a five threads that just returns the character string "Result" and appends it to an array titled thread. In another for loop iterated five times the threads are joined to the term x. I am trying to print the result x, which should yield a list that looks like ['Resut','Result','Result','Result','Result'] but instead the print command only yields the title of the thread and the fact that it is closed. Im obviously misunderstanding how to use threads in python. If someone could provide an example of how to adequately complete this test case I would be very grateful.
import threadingdef Thread_Test():return ("Result")number = 5threads = []for i in range(number):Result = threading.Thread(target=Thread_Test)threads.append(Result)Result.start()for x in threads:x.join()print (x)
There is a difference between creating a thread and trying to get values out of a thread. Generally speaking, you should never try to use return
in a thread to provide a value back to its caller. That is not how threads work. When you create a thread object, you have to figure out a different way of get any values calculated in the thread to some other part of your program. The following is a simple example showing how values might be returned using a list.
#! /usr/bin/env python3
import threadingdef main():# Define a few variables including storage for threads and values.threads_to_create = 5threads = []results = []# Create, start, and store all of the thread objects.for number in range(threads_to_create):thread = threading.Thread(target=lambda: results.append(number))thread.start()threads.append(thread)# Ensure all threads are done and show the results.for thread in threads:thread.join()print(results)if __name__ == '__main__':main()
If you absolutely insist that you must have the ability to return values from the target of a thread, it is possible to override some methods in threading.Thread
using a child class to get the desired behavior. The following shows more advanced usage and demonstrates how multiple methods require a change in case someone desires to inherit from and override the run
method of the new class. This code is provided for completeness and probably should not be used.
#! /usr/bin/env python3
import sys as _sys
import threadingdef main():# Define a few variables including storage for threads.threads_to_create = 5threads = []# Create, start, and store all of the thread objects.for number in range(threads_to_create):thread = ThreadWithReturn(target=lambda: number)thread.start()threads.append(thread)# Ensure all threads are done and show the results.print([thread.returned for thread in threads])class ThreadWithReturn(threading.Thread):def __init__(self, group=None, target=None, name=None,args=(), kwargs=None, *, daemon=None):super().__init__(group, target, name, args, kwargs, daemon=daemon)self.__value = Nonedef run(self):try:if self._target:return self._target(*self._args, **self._kwargs)finally:del self._target, self._args, self._kwargsdef _bootstrap_inner(self):try:self._set_ident()self._set_tstate_lock()self._started.set()with threading._active_limbo_lock:threading._active[self._ident] = selfdel threading._limbo[self]if threading._trace_hook:_sys.settrace(threading._trace_hook)if threading._profile_hook:threading. _sys.setprofile(threading._profile_hook)try:self.__value = True, self.run()except SystemExit:passexcept:exc_type, exc_value, exc_tb = self._exc_info()self.__value = False, exc_valueif _sys and _sys.stderr is not None:print("Exception in thread %s:\n%s" %(self.name, threading._format_exc()), file=_sys.stderr)elif self._stderr is not None:try:print(("Exception in thread " + self.name +" (most likely raised during interpreter shutdown):"), file=self._stderr)print(("Traceback (most recent call last):"), file=self._stderr)while exc_tb:print((' File "%s", line %s, in %s' %(exc_tb.tb_frame.f_code.co_filename,exc_tb.tb_lineno,exc_tb.tb_frame.f_code.co_name)), file=self._stderr)exc_tb = exc_tb.tb_nextprint(("%s: %s" % (exc_type, exc_value)), file=self._stderr)finally:del exc_type, exc_value, exc_tbfinally:passfinally:with threading._active_limbo_lock:try:del threading._active[threading.get_ident()]except:pass@propertydef returned(self):if self.__value is None:self.join()if self.__value is not None:valid, value = self.__valueif valid:return valueraise valueif __name__ == '__main__':main()