Python 关于 flask 中 点击按钮后,后端终止线程的问题

火山草 · 2021年07月08日 · 最后由 火山草 回复于 2021年07月12日 · 5315 次阅读

目前做了一个接口脚本工具类的 web 页面。输入相关字段后,点击按钮,通过 ajax 发送相关字段到后台。后台使用这些字段进行跑接口的脚本。
但是发现一个问题,比如我第一次点击后,后台开始跑接口脚本了。但是我这个时候又点击了,我如何把后台上一次正在跑的接口脚本,终止掉。
目前我的想法是 这个接口脚本使用多线程的跑,每次跑之前,看看有没有之前的线程再跑,有的话就终止线程。但是,搜索了相关信息,没有很好可以终止线程的方法。

相关代码
ajax

对应的接口方法 run_cmd 方法 里面就是持续跑接口 (request) 的步骤

自定义的线程

共收到 14 条回复 时间 点赞

😂 😂 😂 没人吗

缺少你这边的关键信息,但我还是边询问边尝试回答下吧。
你的 “接口脚本” 是不是按测试用例组织的?如果是,你在点击按钮后,测试用例应该形成一个任务队列,然后多个线程到队列里取出用例并执行。当你点击按钮终止用例执行时,你不应该立即停止执行线程,而是应该通知所有执行线程在执行完当前用例后不再到任务队列里取用例,执行线程都空闲后才可以全部安全地终止掉。

Thirty-Thirty 回复

我需要及时性,就是点击停止后,我跑用例的主线程。直接停止。 还有你说的 “执行线程都空闲后才可以全部安全地终止掉” 可以说说具体要怎么实现吗

Thirty-Thirty 回复

就有点想 pycharm 右上角的 run 按钮一样的功能,点击后运行,再次点击重新运行。不会说存在 2 个线程同时跑。

我现在就正在用某个自动化测试工具,这个工具在用例的执行过程中提供这么个按钮 “Cancel after current project step”,这就是说,点击了这个按钮,当前步骤也要执行完才可以 (安全地) 终止,因为立即结束执行线程可能会导致测试环境变为不可预期的状态,跟拔电源关机一个道理。
具体怎么实现?可以以用例 (case) 或步骤 (step) 为单位生成任务队列,执行线程到队列取任务并执行,然后那个停止按钮给所有线程发出 “停止执行” 的通知,其实发的是:小的们,别再来领任务了,干完手里的活儿告我一声。等线程们都上报自己做完了,就安排他们终止,感谢你们的付出,下岗去吧~!

就像快递小哥正在送单途中,不可能打个电话说你现在就立即停止派送,你不再被困了你自由了!有两种做法。1,把货物带回仓库然后滚吧,数据库软件中叫事物回滚;2,送完这单咱们的合同就 cancel,自动化测试工具中叫 cancel after current...

flask+uwsgi 了解一下

Thirty-Thirty 回复

明白你的意思,但是我目前需求的确是需要马上停止。

火山草 回复

所以你的意思是你之所以做不到马上停止某单派送,是因为你不知道该单是被哪个小哥领走了,是吗?生活中我们都可以根据单号查到是哪个小哥派送的,他的手机号等信息,还不是因为派单领单时登记关联上了小哥的信息,模仿学习下,是不是可以解决你目前的问题?

Thirty-Thirty 回复

我可以知道的(想停止的线程的 ID),但是 threading 模块没有终止线程的方法,搜了下,python 的多线程是没办法主动终止线程的,只能通过主线程停止 来使子线程停止。但是我我的主线程是 flask 服务,不可能让他停止的。

火山草 回复

哦,这就是个更靠近开发技术的问题了,我开发技术一般,但我知道社区里开发和测试都好的人@chenhengjie123,我们请教下他?

Thirty-Thirty 回复

嗯嗯

火山草 回复

你这个立即停止,线程应该没法满足。

1、目前应该没怎么提供直接停止线程的方法,大多是在线程内部执行时通过一些轮询来确认是否有停止记号,如果有记号就线程自己停掉,没记号就继续执行。
2、另外,python 的线程由于解释器有 GIL 限制,和其它编程语言不大一样,实际并没法通过多线程用到 cpu 的多核性能,有点像是 伪并发 。所以 python 并行多任务大多用的多进程,多线程用得比较少一些,一般只会用在异步任务(比如等待网络 io)。不过看你这个场景应该用不着榨干性能,应该还好。

你这个场景,建议可以考虑改为用多进程(multiprocessing)?多进程的话通过 kill 发不同的信号量,可以做到仅给退出信号(类似 ctrl+c),或者强制直接杀死进程(操作系统直接杀,进程自己没有拒绝权利,比较符合你说的这个要求)。

陈恒捷 回复

好的 我用多进程是试试 感谢指点

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册