调用第二个函数时如何终止正在运行的第一个Python函数
解决方案
问题根因
当前两个函数由独立的HTTP请求触发,Web服务默认会为不同请求分配独立的线程/进程处理,两个无限循环没有关联控制逻辑,因此会并行运行。
实现代码
通过全局运行状态标记+线程追踪的方式实现调用a2时立即终止a1,修改后可运行的代码如下:
import time import threading from django.shortcuts import render # 全局控制标记:标记a1是否允许运行,以及存储a1的运行线程 a1_allow_run = False a1_exec_thread = None def a1(request): global a1_allow_run, a1_exec_thread if request.method == "POST": add = int(request.POST['addition']) a1_allow_run = True # 将无限循环逻辑放到子线程执行,避免阻塞请求正常返回 def a1_loop(): nonlocal add while a1_allow_run: add += 1 print(add) time.sleep(2) a1_exec_thread = threading.Thread(target=a1_loop, daemon=True) a1_exec_thread.start() return render(request, "blog/finished.html") def a2(request): global a1_allow_run, a1_exec_thread if request.method == "POST": # 先终止a1的运行 a1_allow_run = False if a1_exec_thread and a1_exec_thread.is_alive(): a1_exec_thread.join() # 执行a2自身的业务逻辑 check = request.POST['checking'] while True: print(check) print("second function: ", check) time.sleep(2) return render(request, "blog/finished.html")
注意事项
- 以上实现仅适用于单进程部署的Web服务,若采用多进程部署(如uWSGI、Gunicorn开启多worker),需要改用Redis等公共共享存储存放
a1_allow_run状态,实现跨进程的状态同步 - 子线程设置
daemon=True属性,会随主进程退出自动销毁,避免产生孤儿线程占用资源 - 若后续需要支持a2也被其他请求终止,可以参照a1的逻辑为a2添加对应的控制标记和线程存储变量
内容的提问来源于stack exchange,提问作者Gopi Nath
相关产品推荐
相关产品推荐

