Gunicorn 无法杀死外部进程

Gunicorn not able to kill an external process

你好,我有一个用 Flask 编写的 Web 应用程序,它连接到 USB 信用卡刷卡器。 swiper 的代码是用 java 写的,我的 flask app 是这样的

@app.route("/swipe")
def index():
    a = Popen(["sudo", "java", "sample"], shell=False)
    sts2 = os.waitpid(p.pid, 0)
    return "hello"


@app.route("/kill_swiper", methods=["POST"])
def index_2():
    try:
        pid = request.json
        pid = pid.get("pid")
        os.kill(int(pid), signal.SIGTERM)
        return Response(json.dumps({"status": True}), status=200, mimetype='application/json')

    except Exception as e:
        print(e)
        return Response(json.dumps({"status": False}),
                        status=417, mimetype='application/json')


if __name__ == '__main__':
    app.config['TEMPLATES_AUTO_RELOAD'] = True
    app.run(host="0.0.0.0")

只要用户单击按钮,就会触发刷卡器,将他重定向到可以刷卡或单击取消的页面。

关于我的问题,我可以通过 运行ning 命令

从外部杀死 swiper

sudo kill <pid of swiper>

但是当我尝试点击网站上的取消按钮时,它并没有被杀死。我正在 运行ning gunicorn 后面的烧瓶应用程序,我正在使用以下命令 运行 gunicorn

sudo gunicorn --bind 0.0.0.0:5000 --workers 3 app:app

我尝试将线程作为一个选项,但它没有用。谁能告诉我哪里错了

已更新

使用sudo创建两个进程;父 sudo 进程和运行实际命令的子进程。大多数信号(包括 SIGTERM)应该从父 sudo 进程传递到子进程,但是,在各种情况下它可能不会。可能这正在发生。您需要确保您正在终止子进程。

您应该可以通过 运行 gunicorn 直接作为 root 并删除 sudo 来绕过这个问题。但是,从安全的角度来看,最好避免 运行 服务器进程,例如 gunicorn 作为 root。 java卡reader真的需要吗?如果存在关于打开 USB 端口的权限问题,则有一些解决方法。一些想法可以在这里找到:https://unix.stackexchange.com/questions/72437/how-to-grant-non-root-user-access-to-device-files


os.kill() 正试图终止特权进程(以 sudo 启动),但 flask 进程没有特权。您应该会看到错误响应。

试试 Popen(['sudo', 'kill', pid]) 或类似的方法。

如果您没有收到错误响应,服务器可能会阻止 /swipe 请求中的 os.waitpid(),因此 /kill_swiper 请求不会被处理,直到卡 [=39] =] 进程终止。