1

I want to create one program in which two lists of hosts are available. I want to read data from each host. It will take around 5-10 seconds so I want to read each host data with different thread.

I created below code and it is working as per my expectations but only problem is when I'm pressing Ctrl+c, program didn't terminate.

My code:

import threading
import time,os,sys
import signal

is_running = True

def signal_handler(signal, frame):
    print "cleaning up...please wait..."
    v1.stop()
    v2.stop()
    global is_running
    is_running = False

class Thread2(threading.Thread):
    def __init__(self, function,args):
        self.running = False
        self.function = function
        self.args = args
        super(Thread2, self).__init__()

    def start(self):
        self.running = True
        super(Thread2, self).start()

    def run(self):
        while is_running:
            self.function(self.args)
            time.sleep(time_interval)

    def stop(self):
        self.running = False

def b_iterate(hostnames):

    for host_name in hostnames:
        v = Thread2(function = read_cet_data,args = host_name)
        v.start()

def read_b_data(host):

    #
    #reading some data from current host (5-10 seconds processing)
    #
    #here, this thread is not neccessary, want to stop or kill or terminate it
    if threading.current_thread().isAlive():
        threading.current_thread().stop()

def a_iterate(entp_hostnames):

    for host_name in entp_hostnames:
        v = Thread2(function = read_entp_data,args = host_name)
        v.start()

def read_a_data(host):

    #
    #reading some data from current host (5-10 seconds processing)
    #
    #here, this thread is not neccessary, want to stop or kill or terminate it
    if threading.current_thread().isAlive():
        threading.current_thread().stop()

if __name__ == "__main__":

    signal.signal(signal.SIGINT, signal_handler)
    #a_hostnmaes & b_hostnmaes are the lists of hostnames
    v1 = Thread2(function = a_iterate,args = a_hostnames)
    v2 = Thread2(function = b_iterate,args = b_hostnames)
    v1.start()
    v2.start()
    while is_running:
        pass

How I can make this program terminate after pressing Ctrl+c. Am I missing something?

boardrider
  • 5,882
  • 7
  • 49
  • 86
ketan
  • 2,732
  • 11
  • 34
  • 80
  • check this: https://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python and https://stackoverflow.com/questions/18114560/python-catch-ctrl-c-command-prompt-really-want-to-quit-y-n-resume-executi – Drako Jun 15 '17 at 13:02
  • @Drako- I checked it. My program didn't get terminate because of multiple threads. How I can notify it to terminate. – ketan Jun 15 '17 at 13:15
  • sorry I have never needed anything multi-threading, just lightweight apps that run well on 1 thread :) - no experience with that, just hoped that those links can help with ideas – Drako Jun 15 '17 at 13:24

2 Answers2

0

If you just want control C to finish everything, there is no need to use a stop function in threads. You can just daemonise them:

v1 = Thread2(function = a_iterate,args = a_hostnames)
v2 = Thread2(function = b_iterate,args = b_hostnames)
v1.daemon = True
v2.daemon = True
v1.start()
v2.start()

As soon as your main program dies, these threads die as well. You need to add .daemon = True to all other locations in the code where a thread is created.

Hannu

Hannu
  • 11,685
  • 4
  • 35
  • 51
  • @Hannu- Thanks for your answer. I have a small doubt. In read_b_data and read_a_data functions, how I can terminate or stop this daemon threads? – ketan Jun 16 '17 at 04:42
0

You can either

  • catch KeyboardInterrupt in main thread
  • set a flag so another threads can detect it and exit

or

  • catch KeyboardInterrupt
  • call os._exit()