Reputation: 396
This is my first time working with threading. I think I understand the basics, but I'm not sure how exiting threads work.
Consider the code:
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
self.stoprequest=threading.Event()
def run(self):
while not self.stoprequest.isSet():
print("Starting " + self.name)
print_time(self.name,self.counter)
print("Exiting " + self.name)
def join(self, timeout=None):
self.stoprequest.set()
super(myThread,self).join(timeout)
def print_time(threadName, delay):
time.sleep(delay)
print("%s: %s" % (threadName, time.ctime(time.time())))
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
print("Exiting Main Thread")
From what I understand of threading, they should never end until join()
is called, but the code is exiting after only 1 cycle within the while-loop per thread. The output:
Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Wed Mar 13 09:13:32 2019
Exiting Thread-1
Thread-2: Wed Mar 13 09:13:33 2019
Exiting Thread-2
Note: I did not write this code myself, I found code online and adjusted it to try and get a better understanding of threading.
So my questions:
join()
is never being called? I would expect the threads to be never ending.Thanks!
Upvotes: 0
Views: 268
Reputation: 965
UPDATE
The original answer is wrong, as it misses an important point that @ranjith suggested in comment section.
If you remove the join
function in myThread
definition, you will find that the program will not exit, as @ranjith mentioned. The reason is because, when the main thread exists, it automatically calls join
on all its non-daemon threads, as shown here in the source code. If you never implement join
for your myThread
class, calling join
will return immediately without killing the child threads.
In your case, join
is correctly implemented, which sets the self.stoprequest
event to true, signaling the two child threads to stop. Therefore, when the main thread exits, the two children also exit.
Finally, one note on the differences between implementing join
correctly vs not implementing join
but set daemon
to true, although they both behave similarly (child threads stop when main thread exists). If daemon
is set to true, child threads will not be wait til stop when main thread exits (see Note in this section), while implementing join
does the opposite.
original answer below
This is because your python program exits, so that all children threads are killed implicitly. You need to keep your program running in order to see the two children threads keep printing things.
For example, replace the print statement at the end with this:
while True:
print_time('Main', 3)
Upvotes: 1
Reputation: 361
From what I understand of threading, they should never end until join() is called
This is not true. It totally depends on how you implement the task to run in a thread. Either by overriding Thread class's run method or providing as your task (callable such as a function) as target (which will be called within Thread's run method ). Thread ends when the task terminates or when there is some sort of exception. join method on the Thread is there to essentially wait until thread/s terminate. You can also provide timeout (wait for only certain time)
1. In the above code, why are the threads only executing one cycle of the while loop when join() is never being called? I would expect the threads to be never ending.
How do you know its executing one cycle ? With your code, my tasks are running forever My output,
Starting Thread-2
Thread-1: Wed Mar 13 12:03:42 2019
Exiting Thread-1
Starting Thread-1
Thread-1: Wed Mar 13 12:03:43 2019
Exiting Thread-1
Starting Thread-1
Thread-2: Wed Mar 13 12:03:44 2019
Exiting Thread-2
Starting Thread-2
Thread-1: Wed Mar 13 12:03:44 2019
Exiting Thread-1
Starting Thread-1
Thread-1: Wed Mar 13 12:03:46 2019
Exiting Thread-1
Starting Thread-1
#and goes on
How would I make a threading program run until the user decides to exit it? My main goal is to have a script scan and analyze files until the user tells it to quit.
Depends on how you write your target/ runnable method. You can have logics there to run forever. Think of thread as a piece of work that is being spun off off current (main) program. You should design your tasks to be atomic and simple !
Read more here
Upvotes: 0