title: Killing All Threads in Python
body: <p>I have a python script that will constant ping some IPs and print the results to the screen. 
  But I want to terminte the script via a key press (ideally using the q key or via a ctrl c) and then for all threads to be terminated.</p>
  
  <p>What is the best way to achieve this ? My code is below...</p>
  
  <pre><code>import os
  import re
  import time
  import sys
  import subprocess
  import Queue
  import threading
  
  def screen_output(x, y, text):
       sys.stdout.write("\x1b7\x1b[%d;%df%s\x1b8" % (x, y, text))
       sys.stdout.flush()
  
  class pingo:
  
      def __init__(self,hosts):
          self.q = Queue.Queue()
          self.all_results = {}
          self.hosts = hosts
  
      def send_ping(self,q,ip):
          self.q.put(self.record_results(ip))
  
      def record_results(self,ip):
          ping_count = 0
  
          host_results = {
              "device" : None,
              "sent_count" : 0,
              "success_count": 0,
              "fail_count": 0,
              "failed_perc": 0,
              "curr_status": None
              }
  
  
          while True:
              rc = subprocess.call(['ping', '-c', '1', '-W', '1', ip], stdout=open('/dev/null', 'w'), stderr=open('/dev/null', 'w'))
              ping_count += 1
  
              # update stats
  
              sent_count = host_results['sent_count']
              success_count = host_results['success_count']
              fail_count = host_results['fail_count']
              failed_perc = host_results['failed_perc']
              curr_status = host_results['curr_status']
  
              sent_count += 1
  
              if rc == 0:
                  success_count += 1
                  curr_status = "Successful Response"
              else:
                  fail_count += 1
                  curr_status = "Request Timed Out"
  
              failed_perc =  ( fail_count / sent_count ) * 100
  
              host_results.update({'failed_perc': failed_perc, 'fail_count': fail_count, 'success_count': success_count, 'curr_status': curr_status, 'sent_count': sent_count})
              time.sleep(0.5)
              self.all_results.update({ip:host_results})
              screen_output(0,0,self.all_results)
          return True
  
      def go(self):
          for i in self.hosts:
              t = threading.Thread(target=self.send_ping, args = (self.q,i))
              #t.daemon = True
              t.start()
  
  p =  pingo(["8.8.8.8"])
  p.go()
  </code></pre>
  
  <p>Edit : Ive tried adding a global ALIVE flag as suggested but this still fails to kill the threads via a CRTL-C.</p>
  
  <pre><code>import sys
  import subprocess
  import Queue
  import threading
  import signal
  
  def screen_output(x, y, text):
       sys.stdout.write("\x1b7\x1b[%d;%df%s\x1b8" % (x, y, text))
       sys.stdout.flush()
  
  class pingo:
  
      def __init__(self,hosts):
          self.q = Queue.Queue()
          self.all_results = {}
          self.hosts = hosts
          self.ALIVE = True
  
      def signal_handler(self,signal, frame):
          self.ALIVE = False
  
      def send_ping(self,q,ip):
          self.q.put(self.record_results(ip))
  
      def record_results(self,ip):
          ping_count = 0
  
          host_results = {
              "device" : None,
              "sent_count" : 0,
              "success_count": 0,
              "fail_count": 0,
              "failed_perc": 0,
              "curr_status": None
              }
  
  
          while self.ALIVE:
              try:
                  rc = subprocess.call(['ping', '-c', '1', '-W', '1', ip], stdout=open('/dev/null', 'w'), stderr=open('/dev/null', 'w'))
                  ping_count += 1
  
                  # update stats
  
                  sent_count = host_results['sent_count']
                  success_count = host_results['success_count']
                  fail_count = host_results['fail_count']
                  failed_perc = host_results['failed_perc']
                  curr_status = host_results['curr_status']
  
                  sent_count += 1
  
                  if rc == 0:
                      success_count += 1
                      curr_status = "Successful Response"
                  else:
                      fail_count += 1
                      curr_status = "Request Timed Out"
  
                  failed_perc =  ( fail_count / sent_count ) * 100
  
                  host_results.update({'failed_perc': failed_perc, 'fail_count': fail_count, 'success_count': success_count, 'curr_status': curr_status, 'sent_count': sent_count})
                  time.sleep(0.5)
                  self.all_results.update({ip:host_results})
                  screen_output(0,0,self.all_results)
              except KeyboardInterrupt:
                  signal.signal(signal.SIGINT, self.signal_handler)
          return True
  
  
      def go(self):
          for i in self.hosts:
              t = threading.Thread(target=self.send_ping, args = (self.q,i))
              #t.daemon = True
              t.start()
  
  p =  pingo(["8.8.8.8"])
  p.go()
  </code></pre>