Home > Software design >  Python thread is not alive/finished running but value is not returned yet
Python thread is not alive/finished running but value is not returned yet

Time:01-26

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

  •  Tags:  
  • Related