6

To simplify the situation I'm having: I'm trying to terminate a thread while it is still running in Python 2.7, and I'm not sure how to do it.

Take this simple code:

import time
import threading

def thread1():
        print "Starting thread 1"
        while True:
                time.sleep(0.5)
                print "Working"

thread1 = threading.Thread(target=thread1, args=())
thread1.start()

time.sleep(2)
print "Killing thread 1"
thread2.stop()
print "Checking if it worked:"
print "Thread is: " + str(thread1.isAlive())

Thread 1 keeps on 'working' and I'm trying to kill it in the main thread. Any idea on how to do it? I've tried:

threat1.terminate
threat1.stop
threat1.quit
threat1.end

This all seems to point that there is no way to really stop it with a simple line of code. What could you suggest?

martineau
  • 119,623
  • 25
  • 170
  • 301
user5740843
  • 1,540
  • 5
  • 22
  • 42
  • With processes you can p.terminate() it's not so simple with threads http://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python – brennan Apr 28 '17 at 15:09

3 Answers3

11

To terminate an Thread controlled, using a threadsafe threading.Event():

import threading, time

def Thread_Function(running):
    while running.is_set():
        print('running')
        time.sleep(1)

if __name__ == '__main__':
    running = threading.Event()
    running.set()

    thread = threading.Thread(target=Thread_Function, args=(running,))
    thread.start()

    time.sleep(1)
    print('Event running.clear()')
    running.clear()

    print('Wait until Thread is terminating')
    thread.join()
    print("EXIT __main__")

Output:

running  
running  
Event running.clear()  
Wait until Thread is terminating  
EXIT __main__

Tested with Python:3.4.2


Online Demo: reply.it

stovfl
  • 14,998
  • 7
  • 24
  • 51
  • 1
    Better: Flip the meaning of the `Event` from `running` to `shouldstop`, and don't `set` it, just leave it in its initially unset state. Then change the `while` condition `while not shouldstop.wait(1):` and remove the `time.sleep(1)` call. Now when the main thread calls `shouldstop.set()` (replacing `running.clear()`) the thread responds immediately, instead of needing to wait up to a second for the `time.sleep(1)` to end. Note: On Python 2, this isn't as nice as it could be (because timed `wait` is implemented with a polling loop that does micro-sleeps), but Python 3 is zero overhead. – ShadowRanger Feb 05 '20 at 14:31
4

Usually, in this cases, I use some kind of signal:

import time
import threading

class thread1(threading.Thread):

    def run(self):
        self.kill = False
        print "Starting thread 1"
        while not self.kill:
                time.sleep(0.5)
                print "Working"

thread_obj = thread1()
thread_obj.start()

time.sleep(2)
print "Killing thread 1"
thread_obj.kill = True
print "Checking if it worked:"
time.sleep(1)
print "Thread is: " + str(thread_obj.isAlive())

EDIT

After reading the answer suggested in one of the comment... I realized that this is just a simplified version of what is described there. I hope this will be useful anyway.

Riccardo Petraglia
  • 1,943
  • 1
  • 13
  • 25
2

Indeed!

threads cannot be destroyed, stopped, suspended, resumed, or interrupted

(So say the docs in a paragraph below the link.)

Make your threads listen to signals you may send, via a queue (best), a shared variable (worse), or any other means. Be careful and don't let them run unchecked loops, as in your example code.

9000
  • 39,899
  • 9
  • 66
  • 104