0

0

如何在 Python 中异步执行顺序发送任务而不阻塞循环

花韻仙語

花韻仙語

发布时间:2026-02-05 09:36:29

|

387人浏览过

|

来源于php中文网

原创

如何在 Python 中异步执行顺序发送任务而不阻塞循环

本文介绍如何在保持发送顺序的前提下,用 asyncio 非阻塞地调用同步 api 函数(如 `send_to_space`),避免 for 循环因等待响应而变慢。

在实际开发中,我们常遇到这样的场景:需按序向外部服务(如协作空间 API)逐条发送数据,但每次调用都包含几十毫秒的网络等待;而函数本身是同步阻塞的,又无法修改其内部实现。此时若直接用普通 for 循环,整个流程会线性阻塞(总耗时 ≈ 单次耗时 × 项数)。虽然任务必须顺序发送(不能并发/批量),但我们仍希望不主动等待响应——即发起请求后立即进入下一次迭代,让 I/O 等待在后台完成。

✅ 正确解法是使用 asyncio.create_task() 将每个同步调用“包裹”为协程任务,并立即 await 它——注意:这里的 await 并非等待响应完成,而是等待任务被调度启动(几乎瞬时),从而释放控制权、推进循环。由于 create_task() 将函数提交到事件循环,即使 send_to_space() 是同步函数,它也会在事件循环的默认线程池中异步执行(前提是该函数不阻塞整个解释器,如纯 HTTP 请求通常满足)。

以下是优化后的完整实现:

import asyncio

# 假设 send_to_space 是不可修改的同步函数(例如 requests.post 封装)
def send_to_space(sub_item):
    # 示例:模拟一个耗时 50ms 的同步 HTTP 调用
    import time
    time.sleep(0.05)  # ⚠️ 注意:真实场景中应避免 time.sleep,改用 aiohttp 或线程池
    print(f"Sent: {sub_item}")

async def send_items(items_list):
    for item in items_list:
        sub_item = item['sub_item']
        # 创建任务并立即 await —— 启动执行,不等待完成
        await asyncio.create_task(send_to_space(sub_item))

if __name__ == "__main__":
    my_finite_list = [
        {"sub_item": "A"},
        {"sub_item": "B"},
        {"sub_item": "C"}
    ]
    asyncio.run(send_items(my_finite_list))

⚠️ 重要注意事项:

闪剪
闪剪

AI数字人视频在线创作平台-AI一键成片

下载

立即学习Python免费学习笔记(深入)”;

  • time.sleep() 在协程中会阻塞整个事件循环,因此上述示例仅用于演示逻辑;生产环境中,若 send_to_space() 内部使用 requests 等同步库,请务必通过 asyncio.to_thread()(Python 3.9+)或 loop.run_in_executor() 将其移至线程池执行,否则将失去异步优势:
    async def send_items(items_list):
        for item in items_list:
            sub_item = item['sub_item']
            await asyncio.to_thread(send_to_space, sub_item)  # ✅ 推荐:真正非阻塞
  • await asyncio.create_task(...) 保证了发起顺序,也隐式确保了执行开始的先后;但由于任务在后台线程中运行,若需严格保证「前一个完全结束再发下一个」,则不应使用此方式——而应坚持原始同步调用。本方案适用于「只需按序发起、无需等待结果」的典型日志上报、消息推送等场景。
  • 不推荐使用 threading:多线程虽能并发,但难以优雅控制执行顺序,且线程开销大、GIL 限制明显;asyncio 更轻量、语义更清晰。

总结:当需顺序发起、无需响应、且底层调用可 IO 解耦时,asyncio.to_thread() + await 是 Python 3.9+ 下最简洁、高效、可维护的解决方案。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

589

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

279

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

21

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

23

2026.01.21

http500解决方法
http500解决方法

http500解决方法有检查服务器日志、检查代码错误、检查服务器配置、检查文件和目录权限、检查资源不足、更新软件版本、重启服务器或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

441

2023.11.09

http请求415错误怎么解决
http请求415错误怎么解决

解决方法:1、检查请求头中的Content-Type;2、检查请求体中的数据格式;3、使用适当的编码格式;4、使用适当的请求方法;5、检查服务器端的支持情况。更多http请求415错误怎么解决的相关内容,可以阅读下面的文章。

424

2023.11.14

HTTP 503错误解决方法
HTTP 503错误解决方法

HTTP 503错误表示服务器暂时无法处理请求。想了解更多http错误代码的相关内容,可以阅读本专题下面的文章。

2615

2024.03.12

http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2276

2024.08.16

java连接字符串方法汇总
java连接字符串方法汇总

本专题整合了java连接字符串教程合集,阅读专题下面的文章了解更多详细操作。

7

2026.02.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号