asyncio 混合编程:多线程和多进程的正确打开方式

Python异步编程详解:asyncio和多线程 asyncio` 是 Python 用于解决异步IO编程的标准库,自 Python 3.4 版本引入,并在 Python 3.5 中引入了 `async` 和 `await` 关键字,使得异步代码更加易于编写和理解。- **性能**:`asyncio` 可以提供更高的性能,因为它使用单线程,避免了线程切换的开销。- **复杂性**:`asyncio` 需要使用 `async` 和 `await` 关键字,有一定的学习曲线;- **任务(Task)**:是对协程的进一步封装,它在事件循环中被调度执行。 阅读详情

在异步编程中,有时我们需要结合多线程或多进程来突破单线程的限制。本文将详细介绍两种场景的实现方式。


一、场景对比:何时用多线程?何时用多进程?

特性asyncio + 多线程asyncio + 多进程
适用场景多个独立的事件循环CPU 密集型计算
典型任务① 隔离不同业务模块的异步任务
② 在异步代码中调用不支持async的阻塞库(如requests、PIL、同步数据库驱动)
③ 同步文件IO操作
数据分析、图像处理、科学计算
GIL 限制受限(同一时刻只有一个线程执行 Python 代码)不受限(每个进程有独立的 GIL)
并发模式并发(concurrent):快速切换并行(parallel):真正同时运行
资源开销低(共享内存)高(独立内存空间)
通信方式共享变量(需加锁)进程间通信(队列、管道)

二、asyncio + 多线程:多事件循环架构

多事件循环架构是指在一个Python程序中,同时运行多个独立的事件循环,每个事件循环在自己的线程中运行,管理各自的异步任务。

使用场景

当你需要:

场景1: 多事件循环架构
  • 在不同线程中运行独立的事件循环
  • 隔离不同业务模块的异步任务
  • 避免单个事件循环被某个任务阻塞
场景2: 调用阻塞库

在异步代码中调用不支持 async 的同步库:

  • HTTP 请求库:如 requests(推荐优先使用 aiohttp 等异步库)
  • 图像处理:PIL/Pillow、OpenCV
  • 同步数据库驱动:如某些老旧的 MySQL 驱动
  • 文件 IO 操作:Python 的 asyncio 对文件支持有限
  • 任何会阻塞事件循环的第三方库
场景3: 避免阻塞主循环

防止某个慢任务阻塞整个事件循环,影响其他并发任务。

注意:场景2 是最常见的实际应用,但能用异步库就优先用异步库(性能更好)。

代码示例

import asyncio
import threading
import time
from concurrent.futures import ThreadPoolExecutor


# 定义一个异步任务
async def worker_task(worker_name, job_id, duration):
    print(f"[{worker_name}] 正在处理任务 {job_id},耗时 {duration}s... (线程: {threading.current_thread().name})")
    await asyncio.sleep(duration)
    return f"任务 {job_id} 完成"


# 线程执行函数:负责启动并维持该线程专属的事件循环
def start_async_loop(loop, worker_name):
    asyncio.set_event_loop(loop)
    print(f"线程 {threading.current_thread().name} ({worker_name}) 的事件循环已启动")
    loop.run_forever()


def main():
    # 1. 创建两个独立的事件循环
    loop1 = asyncio.new_event_loop()
    loop2 = asyncio.new_event_loop()

    # 2. 使用线程池管理线程
    with ThreadPoolExecutor(max_workers=2, thread_name_prefix="LoopThread") as executor:
        # 提交任务到线程池
        executor.submit(start_async_loop, loop1, "Worker-1")
        executor.submit(start_async_loop, loop2, "Worker-2")

        # 等待事件循环启动
        time.sleep(0.5)

        start_time = time.perf_counter()
        
        # 3. 从主线程向子线程的事件循环提交异步任务
        f1 = asyncio.run_coroutine_threadsafe(worker_task("Worker-1", "Job-A", 2), loop1)
        f2 = asyncio.run_coroutine_threadsafe(worker_task("Worker-1", "Job-B", 1), loop1)

        f3 = asyncio.run_coroutine_threadsafe(worker_task("Worker-2", "Job-C", 3), loop2)
        f4 = asyncio.run_coroutine_threadsafe(worker_task("Worker-2", "Job-D", 1.5), loop2)

        # 4. 等待任务完成
        print(f"结果反馈: {f1.result()}")
        print(f"结果反馈: {f2.result()}")
        print(f"结果反馈: {f3.result()}")
        print(f"结果反馈: {f4.result()}")
        
        end_time = time.perf_counter()
        print(f"多线程计算总耗时: {end_time - start_time:.2f} 秒")

        # 5. 停止事件循环
        print("\n停止所有事件循环...")
        loop1.call_soon_threadsafe(loop1.stop)
        loop2.call_soon_threadsafe(loop2.stop)

        # 等待线程结束(ThreadPoolExecutor 会在 with 块结束时自动等待)
        print("等待线程池关闭...")

    print("所有线程已关闭")


if __name__ == "__main__":
    main()

关键 API 解析

1. asyncio.new_event_loop()

创建一个新的事件循环对象,用于在独立线程中运行。

loop = asyncio.new_event_loop()
2. asyncio.set_event_loop(loop)

将事件循环设置为当前线程的默认事件循环对象。

asyncio.set_event_loop(loop)
3. asyncio.run_coroutine_threadsafe(coro, loop)

从一个非事件循环线程(即普通线程)向一个正在运行的事件循环(Event Loop)提交协程,返回 concurrent.futures.Future 对象。

future = asyncio.run_coroutine_threadsafe(my_coro(), loop)
result = future.result()  # 阻塞等待结果
4. loop.call_soon_threadsafe(callback)

从一个线程向另一个线程的事件循环(Event Loop)排队执行一个普通的同步回调函数。
它是线程安全版本的 loop.call_soon()。由于 asyncio 的大部分方法不是线程安全的,如果你在非 loop 线程直接调用 loop.call_soon(),可能会导致内部状态混乱

loop.call_soon_threadsafe(loop.stop)  # 停止事件循环

运行效果

线程 LoopThread_0 (Worker-1) 的事件循环已启动
线程 LoopThread_1 (Worker-2) 的事件循环已启动
[Worker-2] 正在处理任务 Job-C,耗时 3s... (线程: LoopThread_1)
[Worker-2] 正在处理任务 Job-D,耗时 1.5s... (线程: LoopThread_1)
[Worker-1] 正在处理任务 Job-A,耗时 2s... (线程: LoopThread_0)
[Worker-1] 正在处理任务 Job-B,耗时 1s... (线程: LoopThread_0)
结果反馈: 任务 Job-A 完成
结果反馈: 任务 Job-B 完成
结果反馈: 任务 Job-C 完成
结果反馈: 任务 Job-D 完成
多线程计算总耗时: 3.01 秒

停止所有事件循环...
等待线程池关闭...
所有线程已关闭

注意事项

  1. 必须停止事件循环:loop.run_forever() 会永远运行,必须调用 loop.stop() 才能退出
  2. 线程安全:从其他线程操作事件循环时,必须使用 _threadsafe 系列方法
  3. 资源管理:使用 with ThreadPoolExecutor 确保线程池正确关闭

三、asyncio + 多进程:CPU 密集型任务处理

使用场景

当你需要:

  • 处理CPU 密集型任务(大量计算)
  • 绕过 Python 的 GIL(全局解释器锁) 限制
  • 充分利用多核 CPU 的计算能力

完整代码示例

import asyncio
import concurrent.futures
import time
import multiprocessing


# 1. CPU 密集型任务:在独立进程中运行
def cpu_bound_calc():
    print(f"进程 {multiprocessing.current_process().name} 开始计算...")
    # 模拟重度计算
    time.sleep(2)
    return "计算完成"


# 2. 异步 IO 任务:在主进程的事件循环中运行
async def io_bound_task(name):
    while True:
        print(f"  [IO 任务 {name}] 正在监控网络...")
        await asyncio.sleep(1)


async def main():
    # 获取当前事件循环
    loop = asyncio.get_running_loop()

    # 3. 创建进程池(建议核数一致或根据需求设定)
    # ProcessPoolExecutor 会创建多个独立的 Python 进程
    with concurrent.futures.ProcessPoolExecutor(max_workers=3) as pool:
        # 启动一个背景 IO 任务,证明主循环没被阻塞
        asyncio.create_task(io_bound_task("Monitor"))

        print("--- 准备向进程池投递计算任务 ---")
        start_time = time.perf_counter()

        # 4. 使用 loop.run_in_executor 将同步函数转为异步调用
        # 这会将 cpu_bound_calc 派发到进程池中的某个进程执行
        tasks = [
            loop.run_in_executor(pool, cpu_bound_calc),
            loop.run_in_executor(pool, cpu_bound_calc),
            loop.run_in_executor(pool, cpu_bound_calc)
        ]

        # 等待所有进程返回结果
        results = await asyncio.gather(*tasks)

        end_time = time.perf_counter()
        print(f"\n计算结果: {results}")
        print(f"多进程计算总耗时: {end_time - start_time:.2f} 秒")


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

关键 API 解析

1. asyncio.get_running_loop()

获取当前正在运行的事件循环(在 async 函数中调用)。

loop = asyncio.get_running_loop()
2. loop.run_in_executor(executor, func, *args)

将同步函数提交到执行器(进程池/线程池)执行,返回一个可 await 的 Future。

future = loop.run_in_executor(pool, cpu_bound_calc)
result = await future
3. asyncio.create_task(coro)

创建并立即调度协程任务,不等待其完成,让任务在后台运行。

task = asyncio.create_task(background_task())  # 立即返回,后台运行
4. ProcessPoolExecutor(max_workers=N)

创建进程池,max_workers 指定进程数量。

with ProcessPoolExecutor(max_workers=4) as pool:
    # 使用进程池

运行效果

--- 准备向进程池投递计算任务 ---
  [IO 任务 Monitor] 正在监控网络...
进程 SpawnProcess-2 开始计算...
进程 SpawnProcess-1 开始计算...
进程 SpawnProcess-3 开始计算...
  [IO 任务 Monitor] 正在监控网络...
  [IO 任务 Monitor] 正在监控网络...
多进程计算总耗时: 2.75 秒

关键观察:

  • IO 任务(网络监控)持续打印,证明事件循环没有被阻塞
  • 3 个 CPU 任务在不同进程中真正并行执行
  • 总耗时约 2 秒(而不是串行的 6 秒)

注意事项

  1. 进程池开销:创建进程比创建线程更耗资源,适合长时间计算
  2. 数据序列化:进程间通信需要序列化数据(使用 pickle),确保参数和返回值可序列化

四、对比总结

技术选型指南

需求方案关键 API
多个独立的事件循环asyncio + 多线程new_event_loop(), run_coroutine_threadsafe()
CPU 密集型计算asyncio + 多进程run_in_executor(), ProcessPoolExecutor
IO 密集型任务纯 asynciogather(), create_task()

性能对比

假设有 3 个任务,每个耗时 2 秒:

方案总耗时说明
串行执行6 秒一个接一个
asyncio(IO 密集)2 秒并发执行,共享单线程
asyncio + 多线程2 秒多个事件循环,但受 GIL 限制
asyncio + 多进程2 秒真正并行,突破 GIL

最佳实践

  1. 优先使用纯 asyncio:如果任务是 IO 密集型,单线程就足够了
  2. CPU 密集型用多进程:避免 GIL 限制,充分利用多核优势
  3. 多线程用于隔离:需要独立事件循环时使用多线程
  4. 注意资源管理:使用 with 语句确保执行器正确关闭
  5. 线程安全第一:跨线程操作必须使用 _threadsafe 方法来保证线程安全

总结

  • asyncio + 多线程:多事件循环架构,适合隔离业务模块
  • asyncio + 多进程:突破 GIL,适合 CPU 密集型计算
  • 核心思想:让异步代码无缝整合同步世界,既保留异步的高效,又解决单线程的瓶颈
Python核心模块实战指南与性能优化技巧 Python模块系统是构建高效应用的基础设施,其核心原理是通过封装可复用代码单元来提升开发效率。在数据处理领域,NumPy的ndarray通过连续内存布局和向量化运算实现数量级性能提升,而Pandas的DataFrame则提供了结构化数据操作的统一接口。这些技术广泛应用于科学计算、金融分析等场景,其中合理使用内存视图(memoryview)和类型化数组能显著优化I/O密集型任务。对于网络编程,asyncio协程模型配合aiohttp库可轻松实现高并发服务,而requests模块简化了HTTP交互的工程实践。 阅读详情

相关推荐

Python并发编程的终极指南:深入理解asyncio与多线程/多进程的比较

为了应对大量并发请求,Python提供了多种并发编程的方式,包括异步编程、多线程和多进程。本文将深入探讨Python中的异步编程模型(使用asyncio)与传统的多线程和多进程模型的异同,以及如何选择合适的并发编程方式来满足实际需求。通过本文的介绍,相信您已经深入理解了Python中的异步编程模型(使用asyncio)与传统的多线程和多进程模型的异同,并了解了如何选择合适的并发编程方式来满足实际需求。多进程是一种并发编程模型,它通过创建多个进程来实现并发执行。下面是一个简单的多进程编程示例,使用。

运维人生 1390

突破性能瓶颈:使用Asyncio构建高并发Python应用程序

不同于多线程,Asyncio 是单线程的,但其内部 event loop 的机制,可以让它并发地运行多个不同的任务,并且比多线程享有更大的自主控制权。Asyncio 中的任务,在运行过程中不会被打断,因此不会出现 race condition 的情况。尤其是在 I/O 操作 heavy 的场景下,Asyncio 比多线程的运行效率更高。因为 Asyncio 内部任务切换的损耗,远比线程切换的损耗要小;并且 Asyncio 可以开启的任务数量,也比多线程中的线程数量多得多。

人生不怕起点低,就怕没追求 1610

参考线平滑-FemPosDeviation-SQP

使用SQP(顺序二次规划)对离散点进行平滑

mpt0816的博客 2439

python中asyncio与多线程结合

multithreading+asyncio总结 第一步:定义需要异步执行的一系列操作,及一系列协程函数; 第二步:在主线程中定义一个新的线程,然后在新线程中产生一个新的事件循环; 第三步:在主线程中,通过asyncio.run_coroutine_threadsafe(coroutine,loop)这个方法,将一系列异步方法注册到新线程的loop里面去,这样就是新线程负责事件循环的执行。 ...

wulong710的专栏 4415

利用netmq在相机应用于unity之间传输图像数据

Unity工业相机接入方案解析 本文探讨了在Unity中接入不同品牌工业相机的技术方案。研究发现: Basler相机可直接调用官方DLL(pylonc.net.dll)实现接入 海康和大恒相机因驱动DLL依赖C++组件,无法直接调用 解决方案:通过独立进程(相机应用程序)与Unity进行通信,采用NetMQ实现图像数据传输 技术实现要点: 相机端:使用PublisherSocket发布JPEG图像帧 Unity端:通过SubscriberSocket订阅图像数据 优化:设置高水位线控制缓存帧数,避免数据堆积

weixin_46450859的博客 417

Python-OpenCV及cv2,numpy库最新安装教程[最全步骤]

安装教程目录前言OpenCV-Python安装教程报错解决cv2安装numpy安装opencv安装(附加)总结 前言 首先,我知道一些看到我的Blog的人已经在网上找了很多歪路子,现在已经火冒三丈了(我也是这样过来的hhhh),那么现在,深呼吸,跟着我的教程,不要着急,每一步都要读一遍。完整安装过程需要1个小时左右(仅供参考,本人第一次安装python花了一天(确信)) OpenCV-Python...

qq_45425286的博客 7431

用 asyncio 实现多线程异步多任务的界面操作

前言最近有个项目需要从窗口客户端发起的异步多任务请求,为了长时间后台操作不卡死前台操作,则还需要发起多线程来隔离 UI 主界面事件循环和 asyncio 后台异步任务事件循环。支持库简介1...

深度觉醒 1478

【论文笔记】Reaching agreement in the presence of faults (EIG)

1 问题定义 2 交互一致性 3 单点故障 m=1 n=4 4 多点故障(n>=3m+1) 计算过程 m=2 n=7 5 n<3m+1不能达成协定 6 带认证的算法 7 总结 这篇论文在1980年发表,是1982年著名的拜占庭将军问题论文的前身。作者Leslie Lamport是2013图灵奖得主,两篇论文引用次数分别为5000+和2000+。该论文提出的算法现在被...

zjwreal 2994

Python Asyncio与多线程/多进程那些事

根据asyncio的文档介绍,asyncio的事件循环不是线程安全的,一个event loop只能在一个线程内调度和执行任务,并且同一时间只有一个任务在运行,这可以在asyncio的源码中观察到,当程序调用get_event_loop获取event loop时,会从一个本地的Thread Local对象获取属于当前线程的event loop: class _Local(threading.local): _loop = None _set_called = False def get_

august5291的博客 2731

数字 IC 笔试面试必考点(2)FPGA 开发流程

FPGA 的详细开发流程就是利用 EDA 开发工具对 FPGA 芯片进行开发的过程,所以 FPGA 芯片开发流程讲的并不是芯片的制造流程,区分于 IC 设计制造流程哟(芯片制造流程多麻烦,要好几十亿的费用呢,而且国内也貌似没有哪家像样的 Foundry 厂,除了台湾的 TSMC 在世界有立足之地,Fabless 的 IC 设计公司倒是挺强的如 Hisilicon,这也是它为什么会被 USA 针对的原因)。

新芯设计的博客 2012

FineBI学习总结

交叉表:一组作为行标题显示在表的左部,另一组作为列标题显示在表的顶部。连接到数据,如果数据不满足数据分析的需求,先进行自助数据集处理。数据集分类:DB表、SQL、Excel、自助数据集。分组表:将报表中的数据按相同项合并为一组显示。1、数据准备2、制作仪表板3、分享仪表板。左合并:保留左边全部数据,合并右边。右合并:保留右边全部数据,合并左边。上下拼接:上下拼接到一张表数据。3、如何实现拼表:多表拼一张。分组–业务包–数据集–字段。字段分类:数值、文本和日期。目录–仪表板–数据准备。维度:文本和日期类型。

Rsun2018的博客 1561

python并发编程:协程asyncio、多线程threading、多进程multiprocessing

python中的asyncioTask对象 Task对象 tasks用于并发调度协程,通过asyncio.creat_task(协程对象)的方式可以创建Task对象,这样可以让协程加入事件循环中等待被调度执行。除了使用asyncio.creat_task()以外,还可以用低层级的loop.creat_task()或asyncio.ensure_future()。 注意:asyncio.creat_task()在python3.7之后加入。在python3.7之前可以改用低层级的asyncio.ensure_

Xzike的博客 7543

基于ESP32的智能车载环境监测系统开发

随着智能汽车技术的飞速发展,车载系统的功能越来越多样化,除了基本的行驶控制和娱乐功能外,车载环境监测系统也成为了一项重要的功能。通过实时监测车内环境数据,例如温度、湿度、空气质量、气体浓度等,智能车载环境监测系统能够提供更为舒适和安全的驾驶体验,同时增强车辆的智能化程度,提升用户的整体体验。ESP32作为一种集成了Wi-Fi和蓝牙功能的高效能低功耗嵌入式开发平台,成为了设计车载环境监测系统的理想选择。它不仅具备丰富的接口和处理能力,还能够实现与云平台、手机应用等系统的远程数据传输和控制。

2201_76125393的博客 715

Python进阶:Asyncio并发编程

和其它Python程序一样,是单线程的,只有一个主线程,但是可以进行多个不同的任务(task),这里的任务,就是特殊的future对象,这些不同的任务,被一个叫做event loop的对象所控制。可以把这里的任务,类比多线程版本里的多个线程上述代码是爬虫的简单示例,四个url一共用了10s的时间,如何用协程进行优化呢?async:声明异步函数,上面的crawl_page和main都成了异步函数await:协程的关键字,后面接异步函数1、当遇到 await 关键字时,协程会暂停自己的执行。

nzbing的博客 1923

【LDPC-7】LLR量化位宽对LDPC译码性能的影响分析——以最小和译码算法为例进行matlab仿真

最小和译码算法的步骤如下:最后译码结果如果满足或者完成所有迭代次数,则译码算法停止迭代,否则继续进行译码迭代操作。

FPGA/MATLAB学习教程/源码/项目合作开发 1471

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Python的asyncio 多线程

多线程、进程、协程是什么就不讲了,(就是你理解的一边呼吸,一边看文章)仅解决问题的话,下边两篇不用看,再深一点的看这个我们这里需求很简单,就是让2个方法都运行!!这里要用的就是asyncio 库。

hzp666的博客 1360

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

深入探究多线程、多进程与异步 I/O

就是这些内容啦,这个话题其实还有很多可以探讨的地方,但我希望已经向大家介绍了各种概念以及何时该使用每种方法。我会定期撰写关于 Python、软件开发以及我所构建的项目的文章,所以请关注我,以免错过精彩内容。下篇文章再见啦!

qq_28791753的博客 1119

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Python中的多线程、进程、协程、threading、asyncio

在讨论场景之前,我们需要将多任务执行的方式进行一下分类,那就是并发方式和并行方式。教科书上告诉我们:并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。

hzp666的博客 1084

Python asyncio 入门实战-4

Python Asyncio Part4

weixin_45357298的博客 749

python asyncio future 多线程_Python Asyncio与多线程/多进程那些事 · 4 Fish

根据asyncio的文档介绍,asyncio的事件循环不是线程安全的,一个event loop只能在一个线程内调度和执行任务,并且同一时间只有一个任务在运行,这可以在asyncio的源码中观察到,当程序调用get_event_loop获取event loop时,会从一个本地的Thread Local对象获取属于当前线程的event loop:class _Local(threading.local...

weixin_42390041的博客 673

python协程系列(七)——asyncio结合多线程解决阻塞问题以及timer模拟

声明:python协程系列文章的上一篇,即第六篇,详细介绍了asyncio的几个底层API概念,asyncio的事件循环EventLoop,Future类的详细使用,以及集中回答了关于异步编程的一些疑问,本文为系列文章的第七篇,将介绍如何使用多线程结合异步编程asyncio,开发出真正“不假死”的应用程序;以及如何模拟一个timer,实现定时操作。 一、异步方法依然会假死(freezin...

MIss-Y的博客 2万+

多线程过时了?asyncio 才是新一代效率神器![特殊字符]揭开 asyncio 的神秘面纱:从慢到快,只差一步之遥 [特殊字符]

asyncio 是 Python 强大的异步编程工具,尤其适合 I/O 密集型任务。它的协程机制让任务切换更高效,事件循环确保了流畅的调度。优点高效处理 I/O 操作。避免多线程的竞争条件问题。支持大规模并发。注意事项使用 asyncio 时,选对兼容的第三方库(如aiohttp对 CPU 密集型任务,应考虑多线程而非 asyncio。学会了 asyncio,你的 Python 技能就升级了好几个档次,跑得比兔子还快!🐇💨。

奔跑的蜗牛 1021

python多线程并行

协程是一种特殊的,可以在执行过程中暂停,也可以稍后恢复执行。协程通过async关键字来指定。await关键字:如果想要立即执行,那调用协程的时候,前面加上关键字。只想创建协程对象稍后执行的话不用加await任务是对协程的封装封装方式:asyncio.create_task(协程)例子事件循环是asyncio的核心组件,负责调度和执行协程。它不断地检查是否有任务需要执行,并在任务完成后调用相应的回调函数。

2401_87427517的博客 534

尽量避免多进程多线程混用,当下死锁

一句话总结:父进程创建子进程时,子进程会复制父进程的内存(包括锁状态),需仔细处理。 1、死锁例子 #include #include #include #include pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void* doit(void* arg) {

Simon的博客 2076

asyncio结合线程池

#使用多线程:在协程中集成阻塞io import asyncio from concurrent.futures import ThreadPoolExecutor import socket from urllib.parse import urlparse def get_url(url): #通过socket请求html url = urlparse...

weixin_34081595的博客 743

如何在django视图中使用asyncio(协程)和ThreadPoolExecutor(多线程)

Django视图函数执行,不在主线程中,直接 loop = asyncio.new_event_loop() # 更不能loop = asyncio.get_event_loop() 会触发 RuntimeError: There is no current event loop in thread 因为asyncio程序中的每个线程都有自己的事件循环,但它只会在主线程中...

bacanlu3823的博客 1542
上一篇: 如何理解asyncio中的事件循环
workind
博客等级 码龄5年 0粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值