Python多线程同步如何实现HTTP请求固定间隔的发送控制
实现方案
方案1:锁+全局最后请求时间(改动最小,适配现有代码)
你之前的锁只实现了请求互斥,只要在锁的临界区增加时间校验和等待逻辑即可满足间隔要求:
- 首先定义全局共享的锁、上次请求时间戳、请求间隔常量:
import threading import time request_lock = threading.Lock() last_request_time = 0 REQUEST_INTERVAL = 5
- 修改线程内的请求逻辑:
while True: headers = get_api_headers() # 临界区:保证时间计算、等待、请求、更新时间全程只有一个线程执行 with request_lock: current_ts = time.time() # 计算需要等待的时长,不足间隔则补等 wait_seconds = REQUEST_INTERVAL - (current_ts - last_request_time) if wait_seconds > 0: time.sleep(wait_seconds) # 等待结束后发起请求 response = requests.get(url, headers=headers, proxies=proxy, verify=cert_file, allow_redirects=False) # 更新最后请求时间为本次请求完成的时间戳 last_request_time = time.time() # 原有业务逻辑保持不变 response.raise_for_status() if response.status_code == 200: html = response.text # 其余业务处理代码
逻辑说明
- 锁保证同一时间只有一个线程能进入请求逻辑,不会出现并发请求
- 每次进入临界区后先校验和上次请求的时间差,不足5秒则休眠补足,确保两次请求的间隔至少为5秒
- 如果需要改成「上一次请求开始后间隔5秒」,只需要把
last_request_time = time.time()放到requests.get之前即可
方案2:独立调度线程(解耦限流与业务逻辑)
如果后续可能调整限流规则,也可以把请求逻辑抽离到独立线程统一调度:
- 定义一个任务队列,所有业务线程将请求参数投递到该队列
- 启动单独的调度线程,循环从任务队列取参数发起请求,每次请求完成后固定sleep 5秒,再处理下一个任务
- 请求结果投递到原有的结果队列供业务逻辑处理
该方案无需在业务线程中加锁,逻辑更清晰,适合复杂度较高的场景。
内容的提问来源于stack exchange,提问作者MatinMoezi
相关产品推荐
相关产品推荐

