Python 并发模型理解:GIL、线程、async 到底是什么关系

Python并发编程实战:从GIL到线程进程选择,解决程序性能瓶颈 并发编程是现代软件开发中的核心概念,旨在通过同时执行多个任务来提升程序效率。其原理基于操作系统对CPU时间片的调度,允许在单核上快速切换任务(并发)或在多核上同时执行任务(并行)。这项技术的核心价值在于最大化硬件资源利用率,尤其对于需要处理大量I/O操作或计算密集型任务的场景。在Python生态中,全局解释器锁(GIL)是一个关键特性,它限制了多线程的并行执行能力,但也确保了内存管理的线程安全。因此,针对I/O密集型任务,如网络请求或文件读写,推荐使用threading模块或asyncio异步框架,它们能在 阅读详情

最近学习Python的FastAPI框架的时候使用了很多Python相关的语法,虽然很多内容都和Java Spring那一套非常的类似,但是Python的并发模型和Java的区别还是非常大的

Python 不是不能多线程,真正的问题是 CPython解释器 有 GIL,所以它的并发策略和 Java 很不一样

总结:

  • Python 可以多线程
  • 但 CPython 有 GIL
  • 所以 I/O 密集型 场景里,多线程和 async 都很好用
  • 但是在CPU 密集型 场景里,多线程通常效果不好,更适合多进程

Global Interpreter Lock(全局解释器锁)

GIL 是 Global Interpreter Lock,全局解释器锁。

它的意思不是:Python 进程里只能有一个线程

它真正的意思是:同一时刻,只有一个线程能执行 CPython 解释器中的 Python 字节码

所以更准确的理解是:

  • 线程可以开很多个
  • 但是如果多个线程都在跑纯 Python 计算代码,它们会轮流抢 GIL

GIL 限制的不是“有没有线程”,而是“多个线程能不能同时执行 Python 字节码”。但是因为这个是对解释器的限制但是没有办法解开的话其实是对并发是有很大的影响的。但是我听说好像有版本已经在尝试或者完成了GIL的移除,这个我没有了解过大家可以去搜搜看

为什么多进程可以解决GIL问题了?

很简单因为每一个进程都是有一个解释器的GIL的,各自去抢各自的锁,因此就每一个并发都不会影响彼此的。但是这样也有问题,最关键的一点就是进程通信的成本和线程通信的成本不是一个级别的。所以这里就是一个trade-off啦

Python的并发调用的两种写法

multiprocessing:多进程(绕开 GIL 的正统方法)

每个子进程有独立解释器 + 独立 GIL → CPU 密集型真正并行;代价是进程创建/IPC 序列化开销。

from multiprocessing import Process, Queue

def worker(i, q):
    q.put((i, cpu_task()))

if __name__ == "__main__":
    q = Queue()
    procs = [Process(target=worker, args=(i, q)) for i in range(4)]
    t0 = time.perf_counter()
    for p in procs: p.start()
    for p in procs: p.join()
    results = [q.get() for _ in procs]
    print(f"multiprocessing: {time.perf_counter() - t0:.2f}s")

threading:多线程(普通多线程)

关键点:CPython 中同一时刻只有一个线程能执行 Python 字节码 → CPU 密集型几乎不加速;但 IO 等待时 GIL 会被释放 → IO 密集型有效。

import threading

def run_threads(task, n=4):
    results = [None] * n

    def worker(i):
        results[i] = task()

    threads = [threading.Thread(target=worker, args=(i,)) for i in range(n)]
    t0 = time.perf_counter()
    for t in threads: t.start()
    for t in threads: t.join()
    print(f"threading: {time.perf_counter() - t0:.2f}s")
    return results

asyc关键字(和Java进行对比)

Python的并发模型不是Java的1:1的而是更类似于Go的M:N模型

  • async def:声明这个函数是个协程函数(coroutine function),调用它不会立即执行,只会返回一个"协程对象"(类似 Java 里的 Supplier<CompletableFuture<T>> 还没 .get() 的状态)。
  • await:在协程里让出控制权,等另一个可等待对象(awaitable)完成,期间事件循环可以去跑别的协程。语义上最接近 Java 的 CompletableFuture.thenCompose / future.get(),但不阻塞线程。
async def hello():        # 协程函数
    return 42

coro = hello()            # ← 这里什么都没跑,只拿到协程对象
print(coro)               # <coroutine object hello at 0x...>

import asyncio
asyncio.run(hello())      # 启动事件循环并跑到完成

async def f()≈ 返回CompletableFuture<T>的方法,但 Python 的协程是惰性的——不await也不run就根本不会执行。Java 的CompletableFuture.supplyAsync(...) 一调用就已经提交到线程池了,这是关键区别

# 方式1:同步函数 → FastAPI 会放到线程池里执行
@app.get("/sync")
def sync_route():
    time.sleep(1)  # 阻塞,但在线程池里,不影响其他请求
    return {"msg": "sync"}

# 方式2:异步函数 → 直接在事件循环里执行
@app.get("/async")
async def async_route():
    await asyncio.sleep(1)  # 挂起,不阻塞事件循环
    return {"msg": "async"}

在FastAPI里面两种方式的声明的区别是很大很大的

async带来的函数染色问题

在有async/await的语言里,函数被分成两种"颜色":

  • 红色函数:async 函数,只能被另一个 async 函数调用(用 await)
  • 蓝色函数:普通同步函数,谁都能调

规则:

  1. 红色函数不能被蓝色函数直接调用(同步代码里没法 await)
  2. 调用红色函数的成本远大于蓝色函数
  3. 一旦某个函数变红,调用链上所有函数都得跟着变红(传染性)

这就是为什么 Python / JavaScript / Rust 的 async 经常被吐槽——async 会向上传染整条调用栈,你写的同步库一旦想接入异步生态,就得整个改写或者包装。

为什么 Java 没有 GIL,而 Python 会有?

最主要的原因就是Java的GC Root的可达性分析的方法去进行GC操作的,但是Python是使用传统的引用计数的方式

CPython:引用计数让线程安全压力非常大

这意味着:

  • 一个对象多一个引用,要 refcount + 1
  • 一个对象少一个引用,要 refcount - 1
  • 而这些操作会非常频繁地发生

如果多个线程同时修改这些对象状态,解释器内部就必须想办法保证线程安全。

GIL 就是一种非常粗但非常有效的方案:

  • 不去给解释器内部无数细节都加锁
  • 而是直接规定:同一时刻只有一个线程执行 Python 字节码

Java:不是引用计数,而是 tracing GC

Java 主要不是靠引用计数回收对象,而是靠 可达性分析,也就是从 GC Roots 出发做 tracing GC。

Java 平时运行时:

  • 不需要每次对象引用变化都去维护一个全局共享 refcount
  • 因此不会像 CPython 一样,因为对象管理机制而天然倾向于引入一把 GIL 这种全局大锁

本质上就是因为这个GC机制的历史问题导致Python的GIL的移除非常的困难

python线程、进程、异步处理及应用,python GIL是什么 python线程、进程、异步详解及应用 阅读详情

相关推荐

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

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

运维人生 1390

Python并发选型指南:GIL原理与线程/进程实战决策

Python并发编程的核心在于理解GIL(全局解释器锁)如何影响CPU密集型与I/O密集型任务的执行效率。GIL并非性能障碍,而是CPython内存安全的保障机制——它在纯计算时强制串行,但在系统调用(如网络、文件读写)时自动释放,使threading天然适配I/O等待场景;而multiprocessing通过独立进程绕过GIL,真正实现CPU并行,但需承担序列化与IPC开销。技术价值在于:基于任务特征(cProfile热点分布)、数据规模(是否触发pickle瓶颈)及依赖安全性(如sqlite3线程限制)

dy_f的专栏 488

Python线程实战指南:GIL原理、线程池调优与I/O并发优化

Python线程并非传统意义的并行执行单元,其核心价值在于高效调度I/O等待间隙——这源于CPython中GIL(全局解释器锁)的设计本质:它不阻止线程切换,仅限制同一时刻仅一个线程执行Python字节码;当线程阻塞于网络、磁盘或sleep时,GIL自动释放,使其他线程得以运行。因此,threading模块天然适配HTTP请求、数据库查询、文件读写等I/O密集型任务,而对CPU密集型场景(如numpy计算、图像处理)则收效甚微。技术价值体现在低开销并发、内存共享便捷与快速启动;典型应用场景包括爬虫集群、微服

weixin_30352645的博客 350

96、Python并发编程:三个核心概念及Python并发编程模型

本文简单介绍了程序到执行的一个大概的过程,辨析了程序、进程、线程的概念,同时简单介绍了Python中的并发编程模型。

南宫理的日知录 1400

ZYNQ开发(2)在Linux系统层上PL-PS通过AXI-DMA传输数据详细步骤及注意事项

参考的网络资料 https://github.com/bperez77/xilinx_axidma/tree/master https://gitlab.gnome.org/HosseinBeheshti/UlteraZed7EV/-/tree/master/petalinux/xilinx_axidma https://www.icode9.com/content-3-925319.html https://blog.youkuaiyun.com/weixin_38218267/article/details/1

aizaiyueye的专栏 3448

Zynq7000双核裸机开发实战:如何安全实现共享内存与乒乓RAM设计

本文深入探讨了Zynq7000双核裸机开发中的共享内存与乒乓RAM设计,重点解析了核间通信的Cache一致性处理机制和硬件级实现方案。通过实战代码示例和性能优化技巧,帮助开发者解决双核运行中的访问冲突问题,提升嵌入式系统开发效率。

weixin_29191669的博客 376

深入理解Python GIL:多线程并发瓶颈与绕过方案

并发编程是提升程序性能的重要手段,而Python开发者常会遇到多线程在计算任务中无法加速的困惑。这背后的核心机制是CPython解释器中的全局解释器锁GIL,它限制了同一时刻仅有一个线程执行Python字节码,从而影响了多线程在CPU密集型任务中的并行能力。理解GIL的存在原理与引用计数内存管理的关系,有助于理性看待Python并发模型的技术价值。在工程实践中,判断任务属于CPU密集型还是I/O密集型是选型关键;对于计算任务可借助多进程或C扩展绕过GIL,而I/O密集场景则适合使用线程池与协程asyncio

weixin_33985679的博客 298

【生产实践】SSH服务弱加密算法修复指南(附完整操作流程)

SSH服务弱加密算法漏洞修复方案 检测发现SSH服务存在支持弱加密算法漏洞,主要风险包括: 使用arcfour、aes128-cbc等易被破解的算法 面临密钥恢复、重放攻击等安全威胁 提供两种修复方案: 推荐方案:升级OpenSSH至最新版本 替代方案:修改SSH配置禁用弱算法(需注意可能影响旧客户端连接) 修复步骤: 编辑/etc/ssh/sshd_config 注释或删除弱算法配置 添加强加密算法(如aes128-ctr等) 重启SSH服务 注意事项: 建议先在测试环境验证 可能需配合客户端升级 操作前

SunMy的博客 3105

Python asyncio库与GIL之间的关系,是否能够解决核心问题?

特性多线程 (threading协程 (asyncio目标实现并发(在单核上)或并行(在多核上,但受GIL限制)在单线程内实现高并发工作模式抢占式多任务(操作系统控制)协作式多任务(代码await控制)最佳场景I/O密集型任务,或者需要与阻塞的C库交互海量I/O 密集型任务(网络、数据库)GIL的影响严重影响CPU 密集型任务的性能,因为无法利用多核。基本无影响,因为它在单线程工作,巧妙地规避了GIL的问题。资源开销线程是操作系统资源,开销较大,不适合开启成千上万个。

Tipriest的博客 1206

什么是论文的创新点?公式化描述算是创新点吗?

写科研论文时,挑战之一就是如何让你的工作“脱颖而出”,也就是要有创新性。不管实验多么精确、推导多么复杂,若没有真正的创新,论文很可能会被拒。关于如何创新问题上,我最近在看刘雪峰老师的《科技论文写作指南》,看到了很多关于写作的新论述,在这里和大家进行分享。

加百力 的技术博客 1926

springcloud教程 -- 1.快速搭建入门级demo,看这一篇就够了

废话不多讲,跟紧我,开启你的SpringCloud初体验 首先回顾微服务的基本组成: [图片 here] 生产者:提供服务 消费者:消费服务 服务注册/发现中心:服务注册,发现,监控 所以,首先明白springcloud微服务的架构基础:生产者(client),消费者(client),服务注册/发现中心(server)

叶巨岩的博客 8万+

从实战理解异步、并发并行与GIL:FastAPI vs SpringBoot

本文探讨了异步编程、并发并行与GIL的关系,对比了FastAPI和SpringBoot的性能特点。关键点包括:1) async/await通过IO等待时释放线程实现高并发;2) GIL仍存在但主要影响CPU密集型任务;3) 并发是任务切换,并行是物理同时执行;4) SpringBoot通过多线程实现并行处理,FastAPI通过异步单线程处理IO密集型任务;5) 在IO密集型场景下,Python的FastAPI同样高效。理解这些概念有助于根据业务场景选择合适的框架。

Aric_Jones的博客 443

实例讲解MOS管电源开关电路的软启动

1、控制电源开关的输入信号 Control 为低电平或高阻时,三极管Q2的基极被拉低到地,为低电平,Q2不导通,进而MOS管Q1的Vgs = 0,MOS管Q1不导通,+5V_OUT 无输出。此时将 Control 设为低电平,三极管Q2关闭,电容C1与G极相连端通过电阻R2放电,电压逐渐上升到5V,起到软关闭的效果。不过从作者的描述来看,只是电路参数有区别,能通过的电流、能承受的耐压等不一样,但是软启动的原理是一样的。从公式可以看出,当电容容量越大,电压越高,时间越短,电流就会越大,从而形成浪涌电流。

U_YAO的博客 2万+

理解python中async和await

async python

youzjuer的博客 2900

024、反激变换器的短路保护设计

本文详细探讨了反激变换器短路保护的设计要点与实践经验。作者通过实际案例分析了短路时反激拓扑的电流特性,指出初级峰值电流限制是最基础的保护手段,但需配合打嗝模式使用。文章重点剖析了打嗝模式设计的三个关键陷阱:频率设定、退出条件和软启动衔接。同时强调次级侧辅助保护、变压器参数优化、环路响应协调的重要性,并比较了自恢复与锁死方案的适用场景。最后提出实测验证的四个关键点和设计经验:不盲信芯片手册、保护电路独立设计、充分留有余量、进行破坏性测试。全文以工程实践为导向,为反激电源的可靠短路保护提供了系统性解决方案。

Jack010169的博客 242

【WRF-Urban】URBPARM_LCZ.TBL 查找表解释及内容

URBPARM_LCZ.TBL 查找表解释及内容

WW、forever的博客 1754

深入理解Python GIL:原理剖析、性能影响与并发优化方案

Python 多线程并发在面对 CPU 密集型任务时,常常会出现性能不升反降的现象,其根源在于 CPython 解释器的全局解释器锁(GIL)。GIL 本质上是一把保护解释器内部状态的大锁,它使得同一时刻只有一个线程能执行字节码。理解 GIL 的存在原因与调度机制,是掌握 Python 并发编程的关键。从内存管理中的引用计数,到线程切换的 5 毫秒时间片,GIL 深刻影响着多线程程序的实际表现。对于 I/O 密集型任务,多线程和协程能有效提升吞吐;而对于计算密集场景,则可借助多进程、本地扩展或向量化运算绕过

weixin_33874713的博客 462

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Python并发编程:线程、多进程、协程与线程池实战

Python并发编程实战:线程、进程与协程的选择指南 本文系统讲解了Python并发编程的核心概念与实践方案。主要内容包括: 并发与并行区别:并发是任务交替执行,并行是真正同时执行 三大方案对比: 多线程:适合IO密集任务,共享内存但受GIL限制 多进程:适合CPU密集任务,可绕过GIL但开销大 协程:轻量级并发,适合高IO并发场景 实战建议: 爬虫/网络请求:多线程可提速近10倍 CPU计算:选择多进程 Web服务:线程池处理阻塞调用 高并发IO:协程最佳 GIL影响:主要制约CPU密集任务的多线程性能,

qq_73077451的博客 586

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Python并发编程实战:进程、线程与GIL原理深度解析

并发编程是现代软件开发的核心概念,旨在通过同时执行多个任务来提升程序效率。其基本原理是利用操作系统提供的进程和线程机制,进程作为资源分配的基本单位提供隔离性,线程作为轻量级执行流共享内存以实现高效协作。这一技术的核心价值在于充分挖掘多核CPU潜力,应对高并发场景,提升系统吞吐量和响应速度。在Python中,并发编程主要应用于Web服务器处理海量请求、数据爬虫并行下载、GUI程序保持界面响应,以及科学计算的并行处理等场景。然而,Python特有的全局解释器锁(GIL)机制对多线程执行CPU密集型任务构成了限制

weixin_34060299的博客 399

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Python进程与线程实战:从GIL原理到并发编程场景选择

并发编程是现代软件开发的核心概念,它通过同时执行多个任务来提升程序效率。其基本原理是利用操作系统提供的进程和线程机制,进程作为资源分配的基本单位提供隔离性,线程作为轻量级执行流共享内存空间。这一技术的核心价值在于充分利用多核CPU资源,提升I/O密集型任务的吞吐量和响应速度。在Python中,全局解释器锁(GIL)是一个关键特性,它使得多线程在CPU密集型任务中无法实现真正的并行,但在I/O密集型场景下,多线程能有效提升性能。实际应用场景包括Web服务器处理并发请求、数据爬虫并行下载、以及科学计算的并行处理

weixin_33713707的博客 657

Python 协程调度:从 yield 到 async/await,理解协程的运行时机制

单线程协作式调度、await 是让出点、阻塞操作必须隔离。理解机制:协程是单线程的,await 是主动让出,事件循环负责调度。这不是魔法,是协作式并发。消灭阻塞:async 函数中禁止同步 IO,用隔离无法避免的阻塞调用。批量调度:用gather并发等待全部、wait灵活控制返回条件、TaskGroup自动管理生命周期。CPU 密集型:用将计算移到进程池,协程只负责调度和 IO。协程不是万能的并发方案,但在 IO 密集型场景中,它是 Python 最轻量、最高效的选择。

no1coder的博客 3278

Python 开发者 Rust 并发进阶指南:从 GIL 限制到编译期线程安全与真并行

> 本文基于开源仓库 RustTraining 的《Rust for Python Programmers》教程第 13 章([python-book/src/ch13-concurrency.md](https://link.gitcode.com/i/61f61d6e351283538d2aed5c716d24a9))展开,系统讲解 GIL 如何限制 Python 并发、Rust 如何用 `S

gitblog_01164的博客 253

【Python】深入理解Python Web框架:从Flask到FastAPI的并发之路

这篇是 Python 基础合集的学习笔记,这次整理的是 Python Web 框架的并发模型。

weixin_63434398的博客 784

Python 并发编程:进程、线程、守护线程与协程

本文面向刚接触 Python 并发的同学,用通俗的语言讲清楚进程、线程、守护线程和协程是什么、怎么用、什么时候用。

2401_83588746的博客 322

Python中 async/await 和传统多线程的区别?

摘要:async/await和多线程是两种并发处理方式,本质差异在于调度机制不同。多线程通过操作系统线程切换实现并发,适合处理IO与CPU混合任务;async/await基于事件循环,在单线程中通过任务切换实现高并发IO处理,但要求全链路异步。选择依据:高并发IO场景用异步,需兼容阻塞库或少量计算的用多线程。两者都存在调试困难问题,且都不适合CPU密集型任务。正确理解两种模式的适用场景和局限性,是技术选型的关键。

程序员学习园地。 879

Java 转 Python 后端 04: GIL 机制、单线程事件循环与异步并发实战

本章系统解析Python并发机制,核心聚焦GIL对多线程的限制及异步编程在Agent后端的必要性。针对I/O密集型场景,推荐使用asyncio协程实现万级并发;CPU密集型任务则需采用多进程突破GIL瓶颈。通过对比Java的CompletableFuture,阐明async/await的调度机制与并发模式差异,强调避免同步阻塞操作。重点实战异步生成器与SSE流式传输,实现大模型输出的实时推送,构建高效、低延迟的Agent服务架构。

2501_93528559的博客 320
上一篇: 动态规划专题Day1——打家劫舍系列
下一篇: 3.5字节广告部门一面面经
晨曦中的暮雨
博客等级 码龄3年 29粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值