简体   繁体   English

当 python 进程被杀死时运行 atexit()

[英]Run atexit() when python process is killed

I have a python process which runs in background, and I would like it to generate some output only when the script is terminated.我有一个在后台运行的 python 进程,我希望它仅在脚本终止时生成一些输出。

def handle_exit():
    print('\nAll files saved in ' + directory)
    generate_output()

atexit.register(handle_exit)

Calling raising a KeyboardInterupt exception and sys.exit() calls handle_exit() properly, but if I were to do kill {PID} from the terminal it terminates the script without calling handle_exit().调用养KeyboardInterupt异常和sys.exit()调用handle_exit()正确,但如果我是做kill {PID}从终端则终止该脚本,而无需调用handle_exit()。

Is there a way to terminate the process that is running in the background, and still have it run handle_exit() before terminating?有没有办法终止在后台运行的进程,并且在终止之前仍然让它运行handle_exit()

Try signal.signal .试试signal.signal It allows to catch any system signal:它允许捕捉任何系统信号:

import signal

def handle_exit():
    print('\nAll files saved in ' + directory)
    generate_output()

atexit.register(handle_exit)
signal.signal(signal.SIGTERM, handle_exit)
signal.signal(signal.SIGINT, handle_exit)

Now you can kill {pid} and handle_exit will be executed.现在你可以kill {pid}并且handle_exit将被执行。

To enable signals when debugging PyCharm on Windows:在 Windows 上调试 PyCharm 时启用信号:

  1. Within PyCharm hit Ctrl + Shift + A to bring up the "Find Actions..." menu在 PyCharm 中Ctrl + Shift + A出“Find Actions...”菜单
  2. Search for "Registry" and hit enter搜索“注册表”并按回车键
  3. Find the key kill.windows.processes.softly and enable it (you can start typing "kill" and it will search for the key)找到关键kill.windows.processes.softly并启用它(你可以开始输入“kill”,它会搜索关键)
  4. Restart PyCharm重启 PyCharm

To check your system and see which signal is being called:要检查您的系统并查看正在调用哪个信号:

import signal
import time


def handle_signal(sig_id, frame):
    sig = {x.value: x for x in signal.valid_signals()}.get(sig_id)
    print(f'{sig.name}, {sig_id=}, {frame=}')
    exit(-1)


for sig in signal.valid_signals():
    print(f'{sig.value}: signal.{sig.name},')
    signal.signal(sig, handle_signal)

time.sleep(30)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM