I have a class FrameThread that inherits from Thread in python
class FrameThread(Thread):
def __init__(self, threadID, customFunction, args):
threading.Thread.__init__(self)
self.threadID = threadID
self.task = customFunction
self.args = args
self.output = None
def run(self):
self.output = self.task(self.args)
The reason I have this class is so that once the thread finishes running my custom function (checking by calling is_alive()), I can retrieve the function returned value.
My program looks something like this
In the first block of code
mythread = FrameThread(threadID, myCustomFunction, args)
mythread.start()
In the second block of code
if not mythread.is_alive():
outputVar = mythread.output
print(outputVar)
This sometimes works and sometimes doesn't. The console either prints out the actual returned value of myCustomFunction or None. So I figured this might be because the value wasn't passed to mythread.output before the python runs 'outputVar = mythread.output'. So I added a loop in the second block of code just for testing.
if not mythread.is_alive():
while mythread.output == None:
print("Reee")
outputVar = mythread.output
print(outputVar)
And to my surprise, the program printed out a bunch of "Reee"s and then printed out the correct value of outputVar.
This behavior is very weird and it's probably because I did something wrong (very likely in my FrameThread class). Please let me know how I could probably fix it, or how to implement the FrameThread subclass properly.
CodePudding user response:
I've checked the code of the threading module and could not find why this is happening. Nevertheless, you can get rid of this problem if you join the thread before getting the result. You should anyway join the thread at some point. You should replace the second block of code by:
if not mythread.is_alive():
mythread.join()
outputVar = mythread.output
print(outputVar)
Using is_alive() like this is seldom useful: it is mostly meant to check if a join has timed out or not. For example:
mythread.join(0)
if mythread.is_alive():
# timed out
print('Still waiting for thread to finish...')
# do some work in the main thread...
else:
outputVar = mythread.output
print(outputVar)
I suggest that you consider using other types of synchronization or concurrent.futures
