Unable to kill Python script with Ctrl-C

I am testing Python threads with the following script:

import threading class FirstThread (threading.Thread): def run (self): while True: print 'first' class SecondThread (threading.Thread): def run (self): while True: print 'second' FirstThread().start() SecondThread().start() 

This works in Python 2.7 on Kubuntu 11.10. Ctrl + C will not kill him. I also tried adding a system signal handler, but this did not help:

 import signal import sys def signal_handler(signal, frame): sys.exit(0) signal.signal(signal.SIGINT, signal_handler) 

To kill a process, I kill it with PID after sending the program to the background with Ctrl + Z , which is not ignored. Why is Ctrl + C ignored so aggressively? How can i solve this?

+103
python linux
Aug 05 '12 at 11:16
source share
3 answers

Ctrl + C terminates the main thread, but since your threads are not in daemon mode, they continue to work, and this keeps working. We can make them demons:

 f = FirstThread() f.daemon = True f.start() s = SecondThread() s.daemon = True s.start() 

But then another problem arises - as soon as the main thread has started your threads, it has nothing more to do. Thus, he exits, and the streams are instantly destroyed. So let keep the live stream:

 import time while True: time.sleep(1) 

Now it will print “first” and “second” until you press Ctrl + C.

Edit: as commenters noted, daemon threads may not be able to clean things like temporary files. If you need it, then catch KeyboardInterrupt in the main thread and copy its cleanup and shutdown. But in many cases, allowing sudden streams of demons is perhaps quite good.

+163
Aug 05 '12 at 11:30
source share

KeyboardInterrupt and signals are visible only to the process (i.e. main stream) ... See Ctrl-c ie KeyboardInterrupt to kill threads in python

+8
Aug 05 '12 at 11:25
source share

I think it is best to call join () on your threads when you expect them to die. I took the liberty with your code to complete the loops (you can also add everything you need to clear there). The die variable is checked for truth at each pass, and when it is True, the program ends.

 import threading import time class MyThread (threading.Thread): die = False def __init__(self, name): threading.Thread.__init__(self) self.name = name def run (self): while not self.die: time.sleep(1) print (self.name) def join(self): self.die = True super().join() if __name__ == '__main__': f = MyThread('first') f.start() s = MyThread('second') s.start() try: while True: time.sleep(2) except KeyboardInterrupt: f.join() s.join() 
+1
Apr 03 '19 at 18:38
source share



All Articles