layout: posttitle: Atexit程序退出前执行操作
subtitle: Atexit程序退出前执行操作
date: 2019-10-31
author: NSX
header-img: img/post-bg-2015.jpg
catalog: true
tags:
- 技术
- 教程
- Python

Python atexit - 退出前执行操作

有时我们需要在Python脚本退出前执行某些操作,或者在测试时需要模拟程序延时退出的影响,我们都可以使用atexit来帮我们实现。

atexit介绍

python atexit模块定义了一个register函数,用于在python解释器中注册一个退出函数,这个函数在解释器正常终止时自动执行,一般用来做一些资源清理的操作(如关闭数据库连接等)。

如果脚本是非正常crash,或者通过os._exit()退出,都不会调用退出函数。

正常退出前执行

  1. import time
  2. import atexit
  3. @atexit.register
  4. def exit_handle():
  5. time.sleep(10)
  6. print('exit')
  7. def echo():
  8. time.sleep(5)
  9. print('abc')
  10. echo()

可以看到在正常退出情况下,例子脚本在等待5秒后打印’abc’,再等待10秒打印完’exit’后,脚本进程才真正结束。
如果在执行time.sleep(5)时CRTL+C,可以看到exit_handle函数是不会执行的。

✨ 被kill时退出前执行

退出函数在脚本被kill时不会产生作用,为了在kill时能正常生效,需要使用signal捕获关闭信号。

  1. import time
  2. import atexit
  3. from signal import signal, SIGTERM
  4. @atexit.register
  5. def exit_handle():
  6. time.sleep(10)
  7. print('exit')
  8. # 使用signal捕获关闭信号,保证被kill时退出前执行
  9. signal(SIGTERM, lambda signum, stack_frame: exit(1))
  10. while True:
  11. pass

上面例子执行时,使用kill方式结束这个例子脚本,会先执行exit_handle函数,等待10秒输出”exit”,然后才会结束。

设置信号处理的函数:signal.signal(signalnum, handler),singnalnum为某个信号,handler为该信号的处理函数。

例子里signal捕获SIGTERM(kill)信号,再执行一个预设函数,返回exit(1),python执行exit()函数时都是正常退出,所以会执行退出函数。

参考

Python atexit - 退出前执行操作

https://www.cnblogs.com/madsnotes/articles/5688681.html

https://www.jb51.net/article/107630.htm