当主线程退出时,守护程序线程会发生什么?他们是如何关闭的?有没有办法确保执行清理代码?
这是我的情况草图:
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 回答
当主线程退出所有守护程序线程时也退出 . 因此,如果你的main()退出所有守护程序线程也会退出 .
然而,并且问题的第二部分,根据官方的python线程docs进行I / O操作,这可能不会优雅地发生 .
因此,如果你想检查周围是否有任何僵尸线程,你可以调用isAlive()函数 . 现在,关于如何确保在主线程死亡后执行清理代码;我认为这取决于你死的意思 .
如果你的意思是正常退出脚本(例如,KeyboardInterrupt异常,调用了sys.exit()),那么真的值得看一下atexit模块,该模块注册在进程终止时要执行的函数 .
如果通过“死亡”意味着main()被信号杀死,或者发生Python致命内部错误,或者调用os._exit(),则atexit模块将无法工作 . 在这种情况下,我想到的一个可能的解决方案是创建另一个监视器进程,该进程持续监视main()并在适当时运行清理代码 .