首页 > 解决方案 > python“信号仅在主解释器的主线程中工作”在带有子进程的烧瓶中

问题描述

我目前正在使用烧瓶网络服务器,并且希望在从父进程触发 ctrl+c 时使用一个函数来完成子进程的工作流程。

main.py是父进程,python3 main.py直接开始。

并且子进程(app.py)是在 .popen(...)之后启动的main.py

# main.py
def get_flask_env():
    flask_env = os.environ.copy()
    if "FLASK_APP" not in flask_env:
        flask_env["FLASK_APP"] = "./server/app.py"
    if "FLASK_ENV" not in flask_env:
        flask_env["FLASK_ENV"] = "development"
    return flask_env

def start_flask():
    flask_env = get_flask_env()
    command = []
    # the command to start app.py, would be: flask run --host 0.0.0.
    command.append(python_command)
    command.append("-m")
    command.append("flask")
    command.append("run")
    command.append("--host")
    command.append("0.0.0.0")
    monitor = subprocess.Popen(command, env=flask_env)

当我启动烧瓶服务器(app.py)时,我在烧瓶服务器中捕捉到错误以处理清除:

def handle_exit(*args):
    # clear multiprocessing here
    pass

然后设置signalin app.py

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

我在父进程(main.py)中成功使用了这个,但是如果我在子进程中使用信号,问题是:

signal only works in main thread of the main interpreter

那么如何正确使用信号子进程呢?

编辑:

目前,我使用subprocess.run(...)linuxmain.py命令终止所有多处理:pkill但这不是跨平台方式,可能会在没有正确等待完成的情况下终止进程。

标签: pythonpython-3.xflasksubprocess

解决方案


行。我的想法是这样的。

import atexit
import os
import subprocess


def teardown(process_handle):
    process_handle.terminate() #kill the sub process clean
    process_handle.wait()# wait for graceful exit.


def get_flask_env():
    flask_env = os.environ.copy()
    if "FLASK_APP" not in flask_env:
        flask_env["FLASK_APP"] = "./server/app.py"
    if "FLASK_ENV" not in flask_env:
        flask_env["FLASK_ENV"] = "development"
    return flask_env


def start_flask():
    flask_env = get_flask_env()
    command = []
    # the command to start app.py, would be: flask run --host 0.0.0.
    command.append(python_command)
    command.append("-m")
    command.append("flask")
    command.append("run")
    command.append("--host")
    command.append("0.0.0.0")
    monitor = subprocess.Popen(command, env=flask_env)
    atexit.register(teardown, monitor) #register to execute at exit

推荐阅读