Gunicorn无法杀死外部进程

时间:2018-03-31 20:56:05

标签: python python-3.x flask gunicorn

您好我有一个用Flask编写的Web应用程序,它连接到USB信用卡刷卡器。 swiper的代码是用java编写的,我的烧瓶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")

每当用户点击一个按钮时,触摸器就会被触发,将他重定向到一个页面,在那里他可以刷卡或点击取消。

遇到我的问题,我可以通过运行命令

从外部杀死swiper

sudo kill <pid of swiper>

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

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

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

1 个答案:

答案 0 :(得分:2)

<强>更新

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

您应该能够通过直接以root身份运行gunicorn并删除sudo来解决问题。但是,从安全角度来看,最好避免以root身份运行gunicorn等服务器进程。 Java读卡器真的需要它吗?如果存在有关打开USB端口的权限问题,可以采用此方法。可以在此处找到一些想法:https://unix.stackexchange.com/questions/72437/how-to-grant-non-root-user-access-to-device-files

os.kill()正试图杀死特权进程(以sudo开头),但烧瓶进程没有特权。您应该看到错误响应。

尝试Popen(['sudo', 'kill', pid])或类似。

如果您没有收到错误响应,则服务器可能会阻止os.waitpid()请求中的/swipe,因此在读卡器进程终止之前,不会处理/kill_swiper请求。< / p>