Arun
Arun

Reputation: 1179

Run a thread for certain time in python

I have a thread which should execute max 3 minutes. if it is exceeds 3 minutes I need to kill it. My current code snippet given below.Please note I can't use multiprocessing module in python.

def test_th():
        p = threading.Thread(target=update_fm,name="update_fm", args=(url,))
        p.start()
        p.join(180)
        log.debug("isalive :",p.isAlive()) 

def update_fm(fv_path):
    output = None
    try:
        output = subprocess.check_output('wget {0} -O /tmp/test_fm'.format(fv_path), stderr=subprocess.STDOUT, shell=True)
    except:
        log.error("Error while downloading package, please try again")
        return FAIL
    if output:
        log.info('going to upgrade cool :)')
        return SUCCESS
    return FAIL

Upvotes: 1

Views: 2269

Answers (1)

Jean-François Fabre
Jean-François Fabre

Reputation: 140297

Since the thread is running a command, you cannot stop it easily (Is there any way to kill a Thread in Python?)

BUT you can help the thread to exit gracefully by killing the process being executed to the thread continues (and exits):

  • replace check_output by Popen
  • get the handle of Popen and make sure it's global
  • after the 3 minutes, kill the handle: the thread exits

Let's simplify it with a standalone example (windows, replace notepad by some other blocking stuff on other platforms):

import threading,subprocess

handle = None

def update_fm():
    global handle
    output = None
    handle = subprocess.Popen('notepad',stdout=subprocess.PIPE)
    output = handle.stdout.read()
    rc = handle.wait()   # at this point, if process is killed, the thread exits with
    print(rc)

def test_th():
        p = threading.Thread(target=update_fm)
        p.start()
        p.join(10)
        if handle:
            handle.terminate()

test_th()

Here, if you close notepad window before the timeout, you get return code 0, and if you wait 10 seconds, the process is killed, you get return code 1.

The difficulty in your error handling will be to tell from "process killed" and "application error". You can set another flag when the process is killed to make the difference.

Upvotes: 2

Related Questions