nhaus
nhaus

Reputation: 1023

Threading program doesn't quit

I am writing a program which constantly checks if certain IP adresses are connected to the network. If they are, nothing happens. If they are not connected for a certain time, an action is triggered. My script works as intended as far as I can tell, however when I try to exit it using ctrl+c it simply doesnt stop. I guess it has something to do with the threading that I am using, but I cant figure out what exactly it is. This is my code so far:

import os
import time
from threading import Timer, Thread
import json

with open("ip_adresses.json", "r") as f:
    ip_adresses_dict = json.load(f)


def timeout():
    print("ACTION IS TRIGGERED")


# dummy Timer thread
print("dummy timer created")
t = Timer(999999999, timeout)
t.daemon = True
try:
    while True:
        ip_adress_reachable = []
        for key, value in ip_adresses_dict.items():
            if os.system(f"ping -c 1 -W 1 {value} > /dev/null") is 0:  # this means its reachable
                ip_adress_reachable.append(True)
            else:
                ip_adress_reachable.append(False)
        print(ip_adress_reachable)

        # if no ip adresses are reachable and no timer running, start a timer.
        if any(ip_adress_reachable) == False and t.is_alive() == False:
            print("starting a new thread")
            t = Timer(15, timeout)
            t.daemon = True
            t.start()

        # If in the meantime ip adress gets reachable cancel the timer.
        elif any(ip_adress_reachable) == True and t.is_alive() == True:
            # cancel the timer
            print("timer was canceled")
            t.cancel()


except KeyboardInterrupt:
    print("quitting")
    t.join(1)

I am kinda lost, because I though that deamon threads would stop after the main loop is done (i.e. after I press ctr+c)

If somebody could help me out, I would be very grateful.

Upvotes: 0

Views: 43

Answers (1)

furas
furas

Reputation: 142641

After testing I found that all problem makes os.system() which catchs Ctrl+C to stop process running in os.system() - ping - and it doesn't send this information to Python.

If you run ping longer and you skip /dev/null

 os.system(f"ping -c 5 -W 1 {value}")

then you will see that Ctrl+C stops ping

If I uses subprocess then I don't have this problem.

 subprocess.call(f"ping -c 1 -W 1 {value} > /dev/null", shell=True)

Code which I used for test on Linux Mint 20 (based on Ubuntu 20.04)

#import os
import time
from threading import Timer, Thread
#import json
import subprocess

#with open("ip_adresses.json", "r") as f:
#    ip_adresses_dict = json.load(f)

ip_adresses_dict = {
    'x': '192.168.0.1',
    'y': '192.168.0.2',
    'z': '192.168.0.3',       
}

def timeout():
    print("ACTION IS TRIGGERED")

# dummy Timer thread
print("dummy timer created")
t = Timer(999999999, timeout)
t.daemon = True

try:
    while True:
        ip_adress_reachable = []
        
        for key, value in ip_adresses_dict.items():
            print('[DEBUG] start process')
            #result = os.system(f"ping -c 1 -W 1 {value} > /dev/null")
            #result = os.system(f"ping -c 5 -W 1 {value}")
            result = subprocess.call(f"ping -c 1 -W 1 {value} > /dev/null", shell=True)
            print('[DEBUG] end process')
            ip_adress_reachable.append( result == 0 )
            
        print(ip_adress_reachable)

        # if no ip adresses are reachable and no timer running, start a timer.
        if any(ip_adress_reachable) is False and t.is_alive() is False:
            print("starting a new thread")
            t = Timer(15, timeout)
            t.daemon = True
            t.start()

        # If in the meantime ip adress gets reachable cancel the timer.
        elif any(ip_adress_reachable) is True and t.is_alive() is True:
            # cancel the timer
            print("timer was canceled")
            t.cancel()
except KeyboardInterrupt:
    print("quitting")
    if t.is_alive():
        t.join(1)
        

Doc: Replacing os.system()

Upvotes: 1

Related Questions