dhyman
dhyman

Reputation: 35

Correctly terminating a thread in Python

I'm not too familiar with threading, and probably not using it correctly, but I have a script that runs a speedtest a few times and prints the average. I'm trying to use threading to call a function which displays something while the tests are running.

Everything works fine unless I try to put input() at the end of the script to keep the console window open. It causes the thread to run continuously.
I'm looking for some direction in terminating a thread correctly. Also open to any better ways to do this.

import speedtest, time, sys, datetime
from threading import Thread

s = speedtest.Speedtest()
best = s.get_best_server()

def downloadTest(tries):
    x=0
    downloadList = []
    for x in range(tries):
        downSpeed = (s.download()/1000000)
        downloadList.append(downSpeed)
        x+=1
        results_dict = s.results.dict()
    global download_avg, isp
    download_avg = (sum(downloadList)/len(downloadList))
    download_avg = round(download_avg,1)
    isp = (results_dict['client']['isp'])
    print("")
    print(isp)
    print(download_avg)

def progress():
    while True:
        print('~ ',end='', flush=True)
        time.sleep(1)


def start():
    now=(datetime.datetime.today().replace(microsecond=0))            
    print(now)
    d = Thread(target= downloadTest, args=(3,))
    d.start()
    d1 = Thread(target = progress)
    d1.daemon = True
    d1.start()
    d.join()

start()
input("Complete...") # this causes progress thread to keep running

Upvotes: 1

Views: 91

Answers (1)

Ali Rasim Kocal
Ali Rasim Kocal

Reputation: 540

There is no reason for your thread to exit, which is why it does not terminate. A daemon thread normally terminates when your programm (all other threads) terminate, which does not happen in this as the last input does not quit.

In general it is a good idea to make a thread stop by itself, rather than forcefully killing it, so you would generally kill this kind of thread with a flag. Try changing the segment at the end to:

killflag = False
start()
killflag = True
input("Complete...")

and update the progress method to:

def progress():
    while not killflag:
        print('~ ',end='', flush=True)
        time.sleep(1)

Upvotes: 1

Related Questions