如何每秒调用run函数持续1分钟且等待所有请求响应后再终止程序
解决方案
你的问题核心是当前通过sleep(60)硬卡退出时间,停止定时器时会直接杀掉还在运行中的run任务,且无法保证所有请求都处理完成。可以通过计数控制调度次数+事件锁等待完成的逻辑解决:
方案1:严格每秒触发1次run(允许并行运行多个run)
该方案保留你原来的固定间隔调度逻辑,严格每1秒触发一次run,总共跑60次,等最后一次run的所有请求返回后再退出:
import requests import time from concurrent.futures import ThreadPoolExecutor from threading import Event, Lock # 这里直接复用你之前的RepeatedTimer实现即可 run_count = 0 count_lock = Lock() max_run_times = 60 all_task_done = Event() urls = [...] data = {} # 补充你自己的请求body参数 def get_url(url): return requests.post(url, data=data) def run(): global run_count # 加锁避免多线程计数冲突 with count_lock: run_count += 1 current_count = run_count # 达到最大次数就停止调度新任务 if current_count > max_run_times: rt.stop() return print(f"starting run {current_count}...") with ThreadPoolExecutor(max_workers=50) as pool: req = pool.map(get_url, urls) res = list(req) success = 0 for r in res: if r.status_code == 200: success += 1 print(f'run {current_count}: {success} successful requests') # 最后一次run执行完毕,触发完成信号 if current_count == max_run_times: all_task_done.set() if __name__ == "__main__": print("starting...") rt = RepeatedTimer(1, run) # 等待所有任务完成再退出,不需要硬sleep固定时长 all_task_done.wait() rt.stop() print("所有请求处理完成,程序退出")
如果你的Python环境安装了原子计数类,也可以替换锁+普通变量的计数逻辑,代码会更简洁。
方案2:上一次run完成后间隔1秒再触发下一次(无并行run)
如果你的需求不需要严格每秒准点触发,而是等上一轮所有请求返回后再等1秒跑下一轮,可以直接用循环实现,不需要引入RepeatedTimer,逻辑更简单不会出现提前退出的问题:
import requests import time from concurrent.futures import ThreadPoolExecutor urls = [...] data = {} def get_url(url): return requests.post(url, data=data) def run(round_num): print(f"starting run {round_num}...") with ThreadPoolExecutor(max_workers=50) as pool: req = pool.map(get_url, urls) res = list(req) success = 0 for r in res: if r.status_code == 200: success += 1 print(f'run {round_num}: {success} successful requests') if __name__ == "__main__": print("starting...") for i in range(60): run(i+1) # 最后一次执行完不需要等待 if i != 59: time.sleep(1) print("所有请求处理完成,程序退出")
内容的提问来源于stack exchange,提问作者ashes999
相关产品推荐
相关产品推荐

