如何在被 Python 殺死之前運行最後一個函數? (How to run one last function before getting killed in Python?)


問題描述

如何在被 Python 殺死之前運行最後一個函數? (How to run one last function before getting killed in Python?)

Is there any way to run one last command before a running Python script is stopped by being killed by some other script, keyboard interrupt etc.

‑‑‑‑‑

參考解法

方法 1:

import time

try:
    time.sleep(10)
finally:
    print "clean up"
    
clean up
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

If you need to catch other OS level interrupts, look at the signal module:

http://docs.python.org/library/signal.html

Signal Example

from signal import *
import sys, time

def clean(*args):
    print "clean me"
    sys.exit(0)

for sig in (SIGABRT, SIGBREAK, SIGILL, SIGINT, SIGSEGV, SIGTERM):
    signal(sig, clean)

time.sleep(10)
#### 方法 2:

You could use the atexit module. With it, you can register a function which will be called at program termination. An example from here: http://docs.python.org/library/atexit.html

try:
    _count = int(open("/tmp/counter").read())
except IOError:
    _count = 0

def incrcounter(n):
    global _count
    _count = _count + n

def savecounter():
    open("/tmp/counter", "w").write("%d" % _count)

import atexit
atexit.register(savecounter)

You can also pass positional and keyword parameters to the function you want to call at program termination.

Note that there are a few circumstances listed in the docs in which your handler won't be called:

  

Note: The functions registered via this module are not called when the program is killed by a signal not handled by Python, when a Python fatal internal error is detected, or when os._exit() is called.

As such, you may want to also register a signal handler.

方法 3:

import signal
import sys
import time

def cleanup(*args):
    print 'Exiting'
    sys.exit(0)

signal.signal(signal.SIGINT, cleanup)
signal.signal(signal.SIGTERM, cleanup)
while True:
    time.sleep(60)  # less busy loop

方法 4:

WIth apologies to 'Unknown' for taking their answer and correcting it as though it was my own answer, but my edits were rejected.

The approved answer contains an error that will cause a segfault.

You cannot use sys.exit() in a signal handler, but you can use os._exit so that it becomes:

from signal import *
import os, time

def clean(*args):
    print "clean me"
    os._exit(0)

for sig in (SIGABRT, SIGINT, SIGTERM):
    signal(sig, clean)

time.sleep(10)

SIGBREAK may be used if the target platform is Windows.

Depending on the use case and the need to cleanup in the event of fatal errors ‑ you may add SIGSEGV and SIGILL but generally this is not advised since the program state may be such that you create an infinite loop.

方法 5:

Use the atexit module to register a function that will be called at the end.

import atexit
atexit.register(some_function)

(by danUnknownjbradaricDaveStuart MSander Marechal)

參考文件

  1. How to run one last function before getting killed in Python? (CC BY‑SA 3.0/4.0)

#interrupt #Python #function #exit






相關問題

無法在 java 命令行程序中捕獲中斷 (Unable to catch interrupt in java command line program)

不連續的 BitBlt 捕獲 (discontinuous BitBlt capture)

GPIO 更改狀態時如何更新 sysfs? (How is sysfs updated when a GPIO changes state?)

Linux IRQ 處理程序中的固有競爭條件 (Inherent race condition in Linux IRQ handlers)

STM32 外部中斷僅在調試模式下響應 (STM32 external interrupt responds only in debug mode)

Java中的線程 (Threading in Java)

如何在被 Python 殺死之前運行最後一個函數? (How to run one last function before getting killed in Python?)

在 C++ 中處理中斷 (Handling Interrupt in C++)

應用程序中斷瘋狂 (Application interrupts like crazy)

SetPriorityClass(REALTIME_PRIORITY_CLASS) 實際上做了什麼? (What does SetPriorityClass(REALTIME_PRIORITY_CLASS) actually do?)

如何找出軟件掛起的原因?(qemu + zephyr + tfm 的問題) (How to find out the cause of hanging software? (problem with qemu + zephyr + tfm))

將參數傳遞給系統調用 (Passing arguments to system calls)







留言討論