Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are daemon threads killed in python (2.7)

What happens to daemon threads when the main thread exits? How are they shut down? Is there a way the ensure that cleanup code is executed?

Here's a sketch of the situation I have:

import os
import subprocess
import threading
import glob
import datetime

def do_big_job(result='result.txt'):
    tmpfile = result+'.tmp'
    err = subprocess.call(['my_time_consuming_script', '-o', tmpfile])
    if err == 0:
        os.rename(tmpfile, result)
    else:
        os.remove(tmpfile) # process failed, clean up temp file



def main():
    not_done = True
    update = 0
    while not_done:

        # we can see if new data are available,
        # and start a process to get/prep it
        if new_data_available():
            args = ('result{0:05}.txt'.format(update),)
            th = threading.Thread(target=do_big_job, args=args)
            update = update + 1
            th.daemon = True 
            th.start()

        # but we don't need/want to wait for that process
        # to complete before continuing to iterate

        currently_available = glob.glob('result*.txt')
        # <snip>
        # rest of loop just uses what is available,
        # we don't want/need to block for updated data
        # to meet other responsiveness requirements

I'd like to make sure that I don't leave any temporary files (or zombie processes) lying around if the main thread dies while one (or more) of the do_big_job threads are still running, but I also can't just set daemon=False since I cannot wait for them to complete when main exits.

like image 751
Dave Avatar asked Nov 03 '16 18:11

Dave


People also ask

How do you kill a daemon thread?

To actively end a (daemon) thread the most common method is to signal the thread the request to have it terminated, the thread should check for this request in regular intervals and end itself once such a request has been made. Voting is disabled while the site is in read-only mode.

What happens to daemon threads Python?

The threads which are always going to run in the background that provides supports to main or non-daemon threads, those background executing threads are considered as Daemon Threads. The Daemon Thread does not block the main thread from exiting and continues to run in the background.

How do you stop a daemon in Python?

This process of stopping the daemon thread can be automated using the atexit module. The atexit module allows a function to be registered that will be called by the Python interpreter right before the process is exited.

How do you close a thread in Python?

We can close a thread by returning from the run function at any time. This can be achieved by using the “return” statement in our target task function. If the threading. Thread class has been extended and the run() function overridden, then the “return” statement can be used in the run() function directly.


1 Answers

When main thread exits all daemon threads exit too. So if your main() exits all daemon threads will exit too.

However, and coming to the second part of your question,according to the official python threading docs for I/O operations this may not happen gracefully.

Daemon threads are abruptly stopped at shutdown. Their resources (such as open files, database transactions, etc.) may not be released properly. If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event.

So if you want to check whether there are any zombie threads lying around, you can call the isAlive() function. Now as to how to ensure that cleanup code is executed after the main thread dies; I think it depends on what you mean by dies.

If you mean normal exit of the script (e.g. KeyboardInterrupt exception, sys.exit() is called) then it's really worth taking a look at the atexit module, which registers functions to be executed upon the termination of a process.

If by "dying" you mean that main() is killed by a signal, or a Python fatal internal error occurs, or os._exit() is called then atexit module won't work. In that case, a possible solution that comes to my mind would be to create another watchdog process that is constantly monitoring your main() and will run the cleanup code when appropriate.

like image 63
kingJulian Avatar answered Nov 15 '22 08:11

kingJulian