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

时间:2016-11-03 18:56:26

标签: multithreading 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,因为我不能等到主要退出时完​​成它们。

1 个答案:

答案 0 :(得分:1)

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

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

  

守护程序线程在关闭时突然停止。他们的资源(例如打开文件,数据库事务等)可能无法正确发布。如果您希望线程正常停止,请使它们成为非守护进程并使用合适的信号机制,例如事件。

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

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

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