python的全局解释锁(GIL)

news2024/11/19 9:35:41

一、介绍

全局解释锁(Global Interpreter Lock,GIL)是在某些编程语言的解释器中使用的一种机制。在Python中,GIL是为了保证解释器线程安全而引入的。

GIL的作用是在解释器的执行过程中,确保同一时间只有一个线程可以执行Python字节码。这意味着在多线程的情况下,同一时刻只有一个线程可以真正地执行Python代码,其他线程只能等待。这是因为GIL会在解释器的关键部分进行加锁,阻止其他线程的执行。

二、 对多线程 Python 程序的影响

CPU 密集型程序是那些将 CPU 推向极限的程序。这包括进行数学计算的程序,如矩阵乘法、搜索、图像处理等。

I/O 绑定程序是花时间等待输入/输出的程序,这些输入/输出可能来自用户、文件、数据库、网络等。I/O 绑定程序有时必须等待很长时间,直到它们从源获得所需的内容,因为源可能需要在输入/输出准备就绪之前进行自己的处理,例如,用户考虑在输入提示或在其自己的进程中运行的数据库查询中输入什么。

下面是一个多线程的程序

# single_threaded.py
import time
from threading import Thread

COUNT = 50000000

def countdown(n):
    while n>0:
        n -= 1

start = time.time()
countdown(COUNT)
end = time.time()

print('Time taken in seconds -', end - start)

 

 现在修改了代码,以使用两个线程并行执行相同的倒计时代码:

# multi_threaded.py
import time
from threading import Thread

COUNT = 50000000

def countdown(n):
    while n>0:
        n -= 1

t1 = Thread(target=countdown, args=(COUNT//2,))
t2 = Thread(target=countdown, args=(COUNT//2,))

start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()

print('Time taken in seconds -', end - start)

 再次运行,结果如下:

 两个版本完成所需的时间几乎相同。在多线程版本中,GIL 阻止 CPU 绑定线程并行执行。

GIL 对 I/O 绑定的多线程程序的性能没有太大影响,因为在线程等待 I/O 时,锁在线程之间共享。

但是,线程完全受 CPU 限制的程序,例如,使用线程在部分中处理图像的程序,不仅会因为锁而变成单线程,而且执行时间也会增加,如上例所示,与编写为完全单线程的情况相比,多线程增加的时间是由获取锁和释放锁带来的开销。
 

三、如何摆脱 Python 的全局锁的限制

1、使用多进程方法

每个 Python 进程都有自己的 Python 解释器和内存空间,因此 GIL 不会成为问题。Python 有一个多进程multiprocessing 模块,它让我们可以轻松地创建这样的进程:

from multiprocessing import Pool
import time

COUNT = 50000000
def countdown(n):
    while n>0:
        n -= 1

if __name__ == '__main__':
    pool = Pool(processes=2)
    start = time.time()
    r1 = pool.apply_async(countdown, [COUNT//2])
    r2 = pool.apply_async(countdown, [COUNT//2])
    pool.close()
    pool.join()
    end = time.time()
    print('Time taken in seconds -', end - start)

与多线程版本相比,性能有所提高。

 

 
2、使用 使用并发库,比如cython 、asyncio、gevent、eventlet 等。这些库使用非阻塞 I/O 和协程等技术,可以在单个线程中实现高效的并发处理,避免 GIL 的限制。来避开全局锁

 

3、使用替代Python解释器

Python有多个解释器实现。CPython,Jython,IronPython和PyPy,分别用C,Java,C#和Python编写,是最受欢迎的。GIL 只存在于 CPython 的原始 Python 实现中。如果你的程序及其库可用于其他实现,那么也可以尝试使用它们。当然使用非官方解释器的代价是:无法使Cython.
 

参考:

什么是Python全局锁(GIL),如何避开GIL限制?_python 全局锁___弯弓__的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/898446.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win11安装ubuntu 子系统安装过程及注意事项

第一步 :安装系统必须组件 由于子系统是系统自带组件,需要安装软件支持 第二步:应用商店安装 ubuntu 编辑 编辑 这个时候打开会报错 第三步,运行linux子系统 选择Windows PowerShell 以管理员身份运行) 输入&#…

docker基础操作练习

目录 1.安装docker服务,配置镜像加速器 2.下载系统镜像(Ubuntu、 centos) 3.基于下载的镜像创建两个容器 (容器名一个为自己名字全拼,一个为首名字字母) 4.容器的启动、 停止及重启操作 5.怎么查看正在…

微信个人号二次开发过程、微信ipad协议

友情链接:geweapi.com 点击即可访问 大家好,今天给大家介绍下ipad的具体情况以及特点 傻瓜式API,掌握JAVA、Go、PHP、Python等任意一种后端代码,你就可以 通过API 搭建一个 微信机器人功能 ,用来自动管理微信消息 我们…

常用curl参数及样例讲解

1 缘起 后端/后台项目开发过程中,有两个阶段的接口测试和验证,自测阶段,通过Postman构建请求, 自建一些参数,测试功能以及边界条件,这些都是可以自行掌控的,当完成功能验证与前端对接时&#x…

以创新点亮前路,戴尔科技开辟数实融合新格局

编辑:阿冒 设计:沐由 2023年,对于戴尔科技而言是特殊的一年,这是戴尔科技进入中国市场第25个年头——“巧合”的是,这25年也是中国产业经济发展最快,人们工作与生活发生变化最大的四分之一个世纪。 2023年&…

C# 观察者模式

一、概述 观察者模式是一种常用的设计模式,它属于行为型模式。在C#中,观察者模式通过定义一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这种模式可以实现松耦合,…

关键点检测中的对象关键点相似度

在不断发展的计算机视觉领域,理解物体的精确结构和姿态至关重要。无论是检测杂乱场景中的特定物体,还是实时分析人体姿势,关键点都起着至关重要的作用。对象上的这些独特点通常对应于角、边缘或其他可识别部分,用作识别和跟踪对象的锚点。但是我们如何衡量这些检测到的关键…

Java版本说明

java7 当谈到Java 7对应的JDK版本时,Java SE 7是Java 7的官方JDK版本。Java SE(Standard Edition)是Java平台的标准版本,它提供了Java编程语言的核心库和工具。 Java SE 7的JDK版本是JDK 7。你可以通过以下链接下载Java SE 7的J…

最新AI系统ChatGPT程序源码/支持GPT4/自定义训练知识库/GPT联网/支持ai绘画(Midjourney)+Dall-E2绘画/支持MJ以图生图

一、前言 SparkAi系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。 那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧&#xff01…

Redis中常见的缓存穿透、缓存击穿、缓存雪崩、缓存预热解决方案

文章目录 一、缓存穿透1. 什么是缓存穿透2. 解决方案2.1 无效的key存放到Redis2.2 引入布隆过滤器2.3 如何选择: 二、缓存击穿1. 什么是缓存击穿2. 解决方案 三、缓存雪崩1. 什么是缓存雪崩2. 解决方案2.1 均匀过期2.2 热点数据缓存永远不过期2.3 采取限流降级的策略…

注册中心/配置管理 —— SpringCloud Consul

Consul 概述 Consul 是一个可以提供服务发现,健康检查,多数据中心,key/Value 存储的分布式服务框架,用于实现分布式系统的发现与配置。Cousul 使用 Go 语言实现,因此天然具有可移植性,安装包仅包含一个可执…

【C++学习手札】一文带你认识C++虚继承​​

食用指南:本文在有C基础的情况下食用更佳 🍀本文前置知识:C虚函数(很重要,内部剖析) ♈️今日夜电波:僕らのつづき—柊優花 1:06 ━━━━━━️💟──────── 3:51 …

将Nginx源码数组结构(ngx_array.c)和内存池代码单独编译运行,附代码

在上面一篇的基础上把Nginx源码数组结构也摘录下来,也增加了测试代码,编译运行。 https://blog.csdn.net/katerdaisy/article/details/132358883 《将nginx内存池代码单独编译运行,了解nginx内存池工作原理,附代码》 核心代码&…

C语言刷题训练DAY.8

1.计算单位阶跃函数 解题思路&#xff1a; 这个非常简单&#xff0c;只需要if else语句即可完成 解题代码&#xff1a; #include <stdio.h>int main() {int t 0;while(scanf("%d",&t)!EOF){if (t > 0)printf("1\n");else if (t < 0)pr…

LVS-DR集群(一台LVS,一台CIP,两台web,一台NFS)的构建以及LVS-DR模式工作原理和特点

一.LVS-DR工作模式原理和特点 1.工作模式 2.模式特点 二.构建环境 1.五台关闭防火墙&#xff0c;关闭selinux&#xff0c;拥有固定IP&#xff0c;部署有http服务的虚拟机&#xff0c;LVS设备下载ipvsadm工具&#xff0c;NFS 设备需要下载rpcbind和nfs-utils 2.实现功能 3…

win11调整屏幕亮度

1.右键打开 2.显示更多选项 3.NVIDIA控制面板 4.调整桌面颜色设置 5.亮度

linux 搭建 nexus maven私服

环境&#xff1a; 必须在 linux 环境下&#xff0c;并且已安装 jdk 下载 访问百度网盘链接: https://pan.baidu.com/s/1fHGmQ2jRUAsXyPom2KL8Mw?pwd0000 提取码: 0000 官网下载 Download Archives - Repository Manager 3 (sonatype.com) 部署 &#xff1a; 进入目录&#…

Echarts:象形柱图实现水塔水位的动画、水球图和液位柱子图

一、象形柱图 1、vue中使用象形柱图 效果图&#xff1a; 2、代码实现 <template><div :class"className" :style"{height:height,width:width}"/></template> <script>import echarts from echarts require(echarts/theme/macar…

论文浅尝 | KRACL-利用图上下文和对比学习的稀疏KG补全

笔记整理&#xff1a;李娟&#xff0c;浙江大学博士&#xff0c;研究方向为知识图谱表示学习 论文链接&#xff1a;https://arxiv.org/pdf/2208.07622.pdf 代码链接&#xff1a;https://github.com/TamSiuhin/KRACL 介绍 知识图谱&#xff08;KG&#xff09;通常是不完整的&…

注意力机制——SENet原理详解及源码解析

&#x1f34a;作者简介&#xff1a;秃头小苏&#xff0c;致力于用最通俗的语言描述问题 &#x1f34a;专栏推荐&#xff1a;深度学习网络原理与实战 &#x1f34a;近期目标&#xff1a;写好专栏的每一篇文章 &#x1f34a;支持小苏&#xff1a;点赞&#x1f44d;&#x1f3fc;、…