helloworld95
helloworld95

Reputation: 396

Python: Understanding Threading and Exiting Threads

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:

  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.
  2. 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.

Thanks!

Upvotes: 0

Views: 268

Answers (2)

lnyng
lnyng

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

ranjith
ranjith

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

Related Questions