You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按指定周期无等待请求RestAPI?Thread与asyncio选型及实现

最优方案选择与实现

方案对比与结论

你的场景是固定间隔发送请求,不需要极高并发量,线程(Thread)方案是最优解——原因很简单:改动成本极低,不用重构原有基于requests的代码,学习和实现成本都远低于asyncio。asyncio更适合高并发场景(比如同时发起成百上千个请求),但对你当前的需求来说有点大材小用。

如果未来需要扩展到高并发场景,再切换到asyncio也不迟,现在先用线程方案快速解决问题。

线程方案实现(修改后的代码)

核心改动点:

  • 用threading.Thread把请求逻辑放到后台线程执行,主循环不用等待响应
  • 加线程锁(threading.Lock)保证文件写入的线程安全,避免多线程同时写文件导致数据乱序或损坏
import time
import requests
import threading

# 创建线程锁,保证文件写入安全
file_lock = threading.Lock()
url = 'http://127.0.0.1:8000/data'

def retrieve_data():
    try:
        response = requests.get(url)
        # 写入文件时加锁
        with file_lock:
            with open('save_data.csv', 'a') as file:  # 改用追加模式,避免每次覆盖
                file.write(response.text + '\n')
        return True
    except Exception as e:
        # 打印错误信息方便排查
        print(f"请求出错: {str(e)}")
        return False

interval = 0.5
while True:
    # 启动后台线程执行请求,主循环不用等待
    threading.Thread(target=retrieve_data, daemon=True).start()
    # 主循环按间隔休眠
    time.sleep(interval)

关键说明:

  • 把文件打开方式从w(覆盖)改成a(追加),避免每次请求清空文件
  • 用daemon=True创建守护线程,主程序退出时线程会自动终止
  • 加file_lock确保同一时间只有一个线程写文件,防止数据混乱
  • 捕获异常时打印具体错误,方便排查问题

备选:asyncio方案实现

如果之后需要高并发,推荐用aiohttp替代requests(requests是同步库,无法直接在asyncio中使用),代码如下:

import asyncio
import aiohttp

url = 'http://127.0.0.1:8000/data'
file_lock = asyncio.Lock()  # 异步锁

async def retrieve_data(session):
    try:
        async with session.get(url) as response:
            response_text = await response.text()
            async with file_lock:
                with open('save_data.csv', 'a') as file:
                    file.write(response_text + '\n')
        return True
    except Exception as e:
        print(f"请求出错: {str(e)}")
        return False

async def main():
    interval = 0.5
    async with aiohttp.ClientSession() as session:
        while True:
            # 并发执行请求,主协程继续休眠
            asyncio.create_task(retrieve_data(session))
            await asyncio.sleep(interval)

if __name__ == "__main__":
    asyncio.run(main())

关键说明:

  • 必须用aiohttp作为异步HTTP客户端,不能用requests
  • 用asyncio.create_task创建异步任务,无需等待任务完成
  • 异步场景下用asyncio.Lock保证文件写入安全
  • 用ClientSession复用连接,提升请求性能

内容的提问来源于stack exchange,提问作者ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 11:48:58