在 Popen 之后杀死进程及其所有子进程
Kill process and all its child processes after a Popen
所以我有一个 Flask 端点 A、端点 B 和另外两个脚本 foo.py
和 bar.py
。
当我调用端点 A 时,我将使用 Popen 调用 foo.py
并存储其 PID。
在 foo.py
上,它使用 Popen 调用 bar.py
,这再次使用 Popen 调用 另一个 。在 bar.py
上打开的进程是一个服务器(更具体地说,它是一个 tf-serving 服务器),当我执行 p.wait() 时它将永远挂起。稍后,我想使用端点B来结束由A触发的整个过程。
情况可能是这样的:
Flask 的端点:
import os
import json
import signal
from subprocess import Popen
from flask import current_app
from flask import request, jsonify
@app.route('/A', methods=['GET'])
def a():
p = Popen(['python', '-u','./foo.py'])
current_app.config['FOO_PID'] = p.pid
return jsonify({'message': 'Started successfully'}), 200
@inspection.route('/B', methods=['GET'])
def b():
os.kill(current_app.config['FOO_PID'], signal.SIGTERM)
return jsonify({'message': 'Stopped successfully'}), 200
foo.py:
p = Popen(['python' ,'-u', './bar.py', '--serve'])
while True:
continue
bar.py:
command = f'tensorflow_model_server --rest_api_port=8501 --model_name=obj_det --model_base_path=./model'
p = subprocess.Popen(command, shell=True, stderr=sys.stderr, stdout=sys.stdout)
p.wait()
不幸的是,当我使用端点 B 终止 foo.py
时,bar.py
(即服务器)创建的进程不会结束。 如何杀死服务器?
请考虑 OS 不可知的解决方案。
使用像psutil
这样的包可以让你递归迭代和访问与某个PID相关的所有子进程。这将有效地允许您终止所有嵌套进程。 psutil
https://github.com/giampaolo/psutil.
的文档
import json
import signal
from subprocess import Popen
from flask import current_app
from flask import request, jsonify
from psutil import Process
@app.route('/A', methods=['GET'])
def a():
p = Popen(['python', '-u','./foo.py'])
current_app.config['FOO_PID'] = p.pid
return jsonify({'message': 'Started successfully'}), 200
@inspection.route('/B', methods=['GET'])
def b():
pid = current_app.config['FOO_PID']
parent = Process(pid)
for child in parent.children(recursive=True):
child.kill()
parent.kill()
return jsonify({'message': 'Stopped successfully'}), 200
所以我有一个 Flask 端点 A、端点 B 和另外两个脚本 foo.py
和 bar.py
。
当我调用端点 A 时,我将使用 Popen 调用 foo.py
并存储其 PID。
在 foo.py
上,它使用 Popen 调用 bar.py
,这再次使用 Popen 调用 另一个 。在 bar.py
上打开的进程是一个服务器(更具体地说,它是一个 tf-serving 服务器),当我执行 p.wait() 时它将永远挂起。稍后,我想使用端点B来结束由A触发的整个过程。
情况可能是这样的:
Flask 的端点:
import os
import json
import signal
from subprocess import Popen
from flask import current_app
from flask import request, jsonify
@app.route('/A', methods=['GET'])
def a():
p = Popen(['python', '-u','./foo.py'])
current_app.config['FOO_PID'] = p.pid
return jsonify({'message': 'Started successfully'}), 200
@inspection.route('/B', methods=['GET'])
def b():
os.kill(current_app.config['FOO_PID'], signal.SIGTERM)
return jsonify({'message': 'Stopped successfully'}), 200
foo.py:
p = Popen(['python' ,'-u', './bar.py', '--serve'])
while True:
continue
bar.py:
command = f'tensorflow_model_server --rest_api_port=8501 --model_name=obj_det --model_base_path=./model'
p = subprocess.Popen(command, shell=True, stderr=sys.stderr, stdout=sys.stdout)
p.wait()
不幸的是,当我使用端点 B 终止 foo.py
时,bar.py
(即服务器)创建的进程不会结束。 如何杀死服务器?
请考虑 OS 不可知的解决方案。
使用像psutil
这样的包可以让你递归迭代和访问与某个PID相关的所有子进程。这将有效地允许您终止所有嵌套进程。 psutil
https://github.com/giampaolo/psutil.
import json
import signal
from subprocess import Popen
from flask import current_app
from flask import request, jsonify
from psutil import Process
@app.route('/A', methods=['GET'])
def a():
p = Popen(['python', '-u','./foo.py'])
current_app.config['FOO_PID'] = p.pid
return jsonify({'message': 'Started successfully'}), 200
@inspection.route('/B', methods=['GET'])
def b():
pid = current_app.config['FOO_PID']
parent = Process(pid)
for child in parent.children(recursive=True):
child.kill()
parent.kill()
return jsonify({'message': 'Stopped successfully'}), 200