多线程 – 如何在python中杀死守护程序线程(2.7)

当主线程退出时,守护程序线程会发生什么?他们是如何关闭的?有没有办法确保执行清理代码?

这是我的情况草图:

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

我想确保如果主线程在一个(或多个)do_big_job线程仍然运行时死亡,我不会留下任何临时文件(或僵尸进程),但我也不能只设置daemon = False,因为我不能等待它们在主要退出时完​​成.

最佳答案 当主线程退出所有守护程序线程时也退出.因此,如果你的main()退出所有守护程序线程也会退出.

但是,在问题的第二部分,根据官方python线程docs进行I / O操作,这可能不会优雅地发生.

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.

因此,如果你想检查周围是否有任何僵尸线程,你可以调用isAlive()函数.
现在,关于如何确保在主线程死亡后执行清理代码;我认为这取决于你死的意思.

如果你的意思是正常退出脚本(例如,KeyboardInterrupt异常,调用了sys.exit()),那么真的值得一看atexit模块,该模块记录了在进程终止时要执行的函数.

如果通过“死亡”意味着main()被信号杀死,或者发生Python致命内部错误,或者调用os._exit(),则atexit模块将无法工作.在这种情况下,我想到的一个可能的解决方案是创建另一个监视器进程,该进程持续监视main()并在适当时运行清理代码.

点赞