As an exercise, I try to implement a non blocking mechanism to manage my own pool of threads (I know concurrent.futures). I ended with a problem: threads are always alive, even after they have completed.
I have written this little code to expose the problem.
import threading
import time
class myThread (threading.Thread):
def __init__(self, num):
threading.Thread.__init__(self)
self.num = num 1
def run(self):
print(f">>> {self.name} is starting")
time.sleep(self.num*2.0)
print(f"<<< {self.name} is finishing")
num_threads = 3
threads = []
for i in range(num_threads):
t = myThread(i)
t.start()
threads.append(t)
num_finished_threads = 0
while num_finished_threads < num_threads:
time.sleep(0.5)
for t in threads:
if t.is_alive:
print(f"{t.name} is alive")
else:
t.join()
num_finished_threads = 1
Can anyone explain me the behaviour of python: why those threads are still alive after completion ?
>>> Thread-1 is starting
>>> Thread-2 is starting
>>> Thread-3 is starting
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
<<< Thread-1 is finishing
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
<<< Thread-2 is finishing
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
<<< Thread-3 is finishing
Thread-1 is alive
Thread-2 is alive
Thread-3 is alive
Thanks a lot.
CodePudding user response:
Try calling the is_alive()
function instead of testing the is_alive
attribute.
if t.is_alive():
print(f"{t.name} is alive")
The reason why you didn't get an "...object has no attribute..." error when you tested t.is_alive
is because a Thread
instance has an attribute with that name. But the value of that attribute is the function, and a function is always "truthy."
In order to find out whether or not the thread is alive, you have to call the function.
https://docs.python.org/3/library/threading.html#threading.Thread.is_alive
CodePudding user response:
You're thread will remain alive unless you join
it.
Create a separate for loop to join all threads.
This will wait for the execution to complete, and will close the threads
while num_finished_threads < num_threads:
time.sleep(0.5)
for t in threads:
if t.is_alive:
print(f"{t.name} is alive")
for t in threads:
t.join()
num_finished_threads = 1
print("done")
Thread-12 is starting>>> Thread-13 is starting
Thread-14 is starting
Thread-12 is alive
Thread-13 is alive
Thread-14 is alive
Thread-12 is finishing
Thread-13 is finishing
Thread-14 is finishing
done