首页 > 解决方案 > atexit/sigterm 触发的函数未在终止的进程上调用

问题描述

我有一个烧瓶server,它使用子进程模块运行另一个 python script(特别是另一个烧瓶服务器)。

在 上script,我添加了一个侦听器以在调用 process.terminate() (终止)SIGMTERM, SIGINT, SIGBART时调用退出处理程序。但是,侦听器从不调用退出处理程序serverscript

这是一个示例代码:

服务器:

import subprocess
import os
import shlex
import time

command = shlex.split('python3 /path/to/script.py')
env = os.environ.copy()
env['MY_APP_NAME'] = "myappnameyes"
del env["WERKZEUG_SERVER_FD"]
process = subprocess.Popen(command,
                           shell=False,
                           env=env,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.STDOUT)

time.sleep(10)
process.terminate()

脚本(这是一个 Flask 服务器):

# script.py
from src.utils import termination
from flask import Flask

app = Flask(__name__)
# Some flask routes...

if __name__ == '__main__':
    app.run()

终止.py:

import signal
import sys
import os

def exit_handler(*args):
    os.makedirs('/Users/galshahar/Desktop/PychramProjects/flask_ser/output', exist_ok=True)


# atexit.register(exit_handler) # Tried it also but also does not work

for sig in (signal.SIGABRT, signal.SIGINT, signal.SIGTERM):
    print(f"Registered {str(sig)}", file=sys.stderr)
    signal.signal(sig, exit_handler)

如果我直接运行 script.py,它会按预期将这些打印到 stderr 并调用exit_handler 创建“输出”目录:

Registered Signals.SIGABRT
Registered Signals.SIGINT
Registered Signals.SIGTERM

但是当我将它server作为子进程运行然后调用process.terminate()时,exit_handler永远不会被调用。我也试过用atexit,也是,没有成功。

我不确定我在这里遗漏了什么,现有的答案没有用......

有任何想法吗?谢谢!

标签: pythonsubprocesssignals

解决方案


推荐阅读