我想在浏览器中输入www.xxx.xx / stopwork时终止z进程。
我试过了:
@app.route('/dowork',methods=['POST'])
def dowork():
...............
def workit():
...................
z = Process(target=workit)
z.start()
@app.route('/stopwork', methods=['POST'])
def stopwork():
z.terminate()
return redirect('/')
return redirect('/')
它应该工作 - 进程停止。当我想从浏览器再次调用/ dowork时。 dowork()再次启动,但我在浏览器中出错:
内部服务器错误
服务器遇到内部错误,无法完成您的请求。服务器过载或应用程序出错。
来自应用程序的错误:
现有的端点功能:%s' %端点) AssertionError:视图函数映射正在覆盖现有的端点函数:stopwork
有没有办法在执行z.terminate后将端点设置为空白?所以以后没有覆盖?
答案 0 :(得分:0)
它不能正常工作。从来没有。它似乎可行,但Web应用程序不保证是单线程的,甚至不是单个进程。因此,停止请求可以由与处理启动请求不同的线程甚至进程处理。
您不能指望请求中的任何值可以在另一个请求中访问,除非您以某种方式明确地保留它。在cookie或数据库中。 Process
实例不能以这种方式持久化,因为它的一部分值是外部操作系统级进程。您可以保存其进程ID以及其父进程ID,以确保在发出停止请求时识别该对。这是一个如何使用会话cookie的示例:
from multiprocessing import Process
from time import sleep
import psutil
from flask import Flask, redirect, session, url_for
app = Flask(__name__)
app.secret_key = 'f\xa9\x85\xf0\xe9\x982\xc4\xf8\xa0k\x91\xa7\xef\x12y'
@app.route('/')
def index():
return (
'<form action="/work/start" method="POST">'
'<input type="submit" value="Start">'
'</form>'
'<form action="/work/stop" method="POST">'
'<input type="submit" value="Stop">'
'</form>'
)
def work_it():
while True:
print('working...')
sleep(1)
@app.route('/work/start', methods=['POST'])
def start_work():
if 'work_process' not in session:
process = Process(target=work_it)
process.start()
pid = process.pid
parent_pid = psutil.Process(process.pid).parent().pid
session['work_process'] = (parent_pid, pid)
return redirect(url_for('index'))
@app.route('/work/stop', methods=['POST'])
def stop_work():
if 'work_process' in session:
parent_pid, pid = session['work_process']
try:
process = psutil.Process(pid)
if process.parent().pid == parent_pid:
process.terminate()
except psutil.NoSuchProcess:
pass
session.pop('work_process')
return redirect(url_for('index'))
它使用psutil来获取父进程的PID并终止进程。
这种“解决方案”有一些缺点。如果浏览器允许从不同的选项卡/窗口中分离cookie,则可以按浏览器启动进程,甚至可以从同一浏览器启动进程。 Firefox正在使用私有窗口功能执行此操作。要停止进程,需要cookie。因此,如果您阻止或删除cookie,则无法使用“停止”按钮停止该过程。再次以Firefox为例:关闭私人窗口时,其cookie已消失。
因此,对于更好或甚至是真正的解决方案,您需要存储数据以在某些数据库中识别服务器上的已启动进程。由于Flask与数据库无关,因此我没有提供一个示例,因为您可能在Web应用程序中使用了与我为示例选择的完全不同的数据库方法。