Search code examples
pythoneventsexitatexit

Python: How to make the function run unconditionally when the program ends?


I must ensure that the end_event() function is executed at the end of the program. I tried to implement this as Python's atexit. However, when the .py file was converted to an exe file with a PyInstaller and closed with a click, it did not work. I would appreciate it if you could tell me a solution that always works. Have a good day.

import atexit
import signal
import pyupbit

def end_event():
    for keys in buy_list.keys():
        order = upbit.get_order(keys)
        if "state" in order:
            if(order['state'] == 'wait'):
                upbit.cancel_order(keys)
    exit(1)

atexit.register(end_event)
signal.signal(signal.SIGINT, end_event)

Solution

  • There is no way to guarantee that code will run when the process exits, because there are ways to exit which do not permit any code to run.

    • User may pull the power cable. No code can run because there is no power.
    • External events (power outage, lightning strike), same as above.
    • Kill -9 or equivalent, e.g. Windows' TerminateProcess

    Patterns for emergency cleanup.

    The best pattern is: Never be in a state which requires emergency cleanup.

    • There is no guarantee that your cleanup will run because you could have a kill -9 or a power outage.
    • Therefore you need to be able to recover in that scenario.

    See also: What does the POSIX standard say about thread stacks in atexit() handlers? What's the OS practice?