pythonmultithreadingtimerkill

Custom Threading Timer Kill Function Python


I have a queue with threading setup. I need it to kill the process if it runs longer than 2900s which works fine. I'm wanting to write out information if it has to kill the process because it ran to long. Is there a way to write a custom function for this line:

timer = Timer(2900, recover.kill)

to:

timer = Timer(2900, custom_function(recover))

Where I can run custom_function to do stuff before calling recover.kill? I tried doing this but it doesn't work.

while not q.empty():
try:
    cmd = "itf -obj " + q.get()
    recover = subprocess.Popen(shlex.split(cmd), env=my_env, shell=False)
    timer = Timer(2900, recover.kill)
    try:
        timer.start()

        my_pid, err = recover.communicate()
        recover.wait()
        q.task_done()
    finally:
        print("Completed before time")
        timer.cancel()
except Exception as e:
    q.task_done()
    continue

Thanks!


Solution

  • You can define a custom function like this:

    def custom_function(recover):
        print("Some relevant information")
        recover.kill()
    

    You'll then have to pass this function in to Timer. But be careful - custom_function(recover) isn't a function! Python evaluates it first, then passes the result into Timer, so this is closer to Timer(2900, None). (It will also immediately kill your process.)

    Instead, you can use a lambda expression:

    timer = Timer(2900, lambda: custom_function(recover))
    

    This is confirmed to work with the following program structure:

    import subprocess
    from threading import Timer
    
    def custom_function(recover):
        print("Some relevant information")
        recover.kill()
    
    recover = subprocess.Popen(["python3", "forever_script.py"], shell=False)
    timer = Timer(10, lambda: custom_function(recover))
    timer.start()
    
    # forever_script.py
    from time import sleep
    
    while True:
        print("Testing script...")
        sleep(1)