python之GIL锁详解

目录

1.GIL是什么以及影响

2.为什么会有GIL锁?


1.GIL是什么以及影响

在Python中,多线程的并发性受到全局解释器锁(GIL,Global Interpreter Lock)的影响。GIL是CPython(Python的官方实现)中的一个特性,它的主要目的是确保在任何时候只有一个线程在执行Python字节码。

这是因为CPython的内存管理不是线程安全的,所以需要一个锁来防止多个线程同时修改或访问共享的内存区域。

然而,这并不意味着Python多线程不能实现真正的并发。GIL允许线程之间进行切换,但每次只有一个线程能够持有GIL并执行Python字节码。当线程需要执行I/O操作或调用某些内置函数(如time.sleep)时,它可能会释放GIL,允许其他线程获得执行权。这种切换机制使得Python多线程在某些情况下(如I/O密集型任务)仍然可以实现并发性能的提升。

但是,对于计算密集型任务,Python多线程可能无法充分利用多核CPU的优势,因为GIL限制了同一时间只有一个线程能够执行Python字节码。在这种情况下,使用多进程(multiprocessing)可能是更好的选择,因为多进程允许每个进程拥有自己的GIL和内存空间,从而实现真正的并行执行。

总之,GIL的作用是确保CPython的内存管理在多线程环境中的线程安全性,但它也限制了Python多线程在计算密集型任务中的并发性能。因此,在选择使用多线程还是多进程时,需要根据具体的任务类型和性能需求进行权衡。

GIL并不是Python的特性,Python完全可以不依赖于GIL。

2.为什么会有GIL锁?

原因在于python的内存管理机制采用引用计数机制,引用计数这个变量不是线程安全的,需要用GIL全局锁来进行数据保护。

python中的对象使用引用计数为主,标记清楚和隔代回收为辅来进行内存管理。所有python脚本中创建的对象,都会配备一个引用计数,来记录有多少个指针来指向它。以全局变量a为例,每有一个线程若调用了a,则a的引用计数加1。

注意:全局变量的引用计数并不直接与线程数量相关。全局变量(或任何Python对象)的引用计数仅与其被引用的次数有关。比如有10个线程,但只有9个线程引用该变量,则引用计数为9。

当一个线程引用一个全局变量时,该变量的引用计数增加;当引用被删除(比如线程结束使得引用被删除)或超出作用域(比如局部变量的结束)时,引用计数减少。另外每个线程可以独立地引用或取消引用全局变量,从而影响其引用计数。

当对象的引用计数为0时,Python的垃圾回收器会释放该对象占用的内存。但是,请注意,这并不意味着对象占用的内存会立即返回给操作系统;它可能会被Python的内存管理器保留以供将来使用。

那么为什么需要GIL锁呢,因为这个引用计数变量不是线程安全的,举例说明如下:

  1. 假设开始时只有主线程,引用一个数据(a=100,引用计数x为1),
  2. 若再开启2个python子线程,每个线程的开启都会使得x进行自增1的操作(x+=1),意味着有多个线程对同一个资源的竞争,如果有GIL锁存在的话,x最后正常会变成3
  3. 但是如果没有GIL锁的话,x可能最终是2。这造成的后果是,当第1个子线程结束时,会把引用计数x减少为1;当第2个线程结束时,会把引用计数x减少为0,这时变量a会被释放所占用的内存。之后若主线程再次试图访问a这个数据时,将会程序异常,会无法找到有效的内存,程序会出错。

总结GIL存在的目的:GIL的存在是为了防止在多个线程同时执行Python字节码时,由于内存管理(如引用计数)的并发操作导致的竞态条件。GIL确保在任何时候只有一个线程在执行Python字节码。


end

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AWT的菜单组件

AWT的菜单组件 前言一、菜单组件的介绍常见的菜单相关组件常见菜单相关组件集成体系图菜单相关组件使用小要点 二、AWT菜单组件的代码示例示例一示例二实现思路 前言 推荐一个网站给想要了解或者学习人工智能知识的读者,这个网站里内容讲解通俗易懂且风趣幽默&…

pyqt 文件浏览列表视图和图标视图

pyqt 文件浏览列表视图和图标视图 目的效果代码 目的 使用pyqt实现文件浏览列表视图和图标视图,像电脑文件浏览一样。如下图所示。 效果 代码 import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QToolBar, QAction, Q…

同元软控受邀出席2024年工业软件与新质生产力创新发展论坛

近日,由广东省工业软件学会主办的“2024年工业软件与新质生产力创新发展论坛”在广州成功举办。同元软控深圳子公司副总经理周胜受邀出席,并作《数智驱动创新,科学计算与系统建模仿真加速新质生产力进化》主题演讲。 本次论坛集结工业软件界…

用pycharm进行python爬虫的步骤

使用 pycharm 进行 python 爬虫的步骤:下载并安装 pycharm。创建一个新项目。安装 requests 和 beautifulsoup 库。编写爬虫脚本,包括获取页面内容、解析 html 和提取数据的代码。运行爬虫脚本。保存和处理提取到的数据。 用 PyCharm 进行 Python 爬虫的…

【日常记录】【JS】SSE 流式传输 ChatGPT 的网络传输模式

文章目录 1、SSE 流式传输2、后端代码3、前端代码5、SSE和WS 对比6、chatgpt SSE的服务端返回的数据参考链接 单工通信是一种单向的通信方式,其中信息只能从发送端传输到接收端,而接收端不能向发送端发送任何信息。在Web开发中,Server-Sent E…

【UML用户指南】-24-对高级行为建模-进程和线程

目录 1、概念 2、主动类 3、通信 4、同步 5、常用建模技术 5.1、对多控制流建模 5.2、对进程间通信建模 在UML中,可以将每一个独立的控制流建模为一个主动对象,它代表一个能够启动控制活动的进程或线程。 进程是一个能与其他进程并发执行的重量级…

chrome.storage.local.set 未生效

之前chrome.storage.local.set 和 get 一直不起作用 使用以下代码运行成功。 chrome.storage.local.set({ pageState: "main" }).then(() > {console.log("Value is set");});chrome.storage.local.get(["pageState"]).then((result) > …

JAVA学习笔记-JAVA基础语法-DAY19-File类、递归

第一章 File类 1.1 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。 1.2 构造方法 public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。public File(St…

〔002〕虚幻 UE5 发送 get、post 请求、读取 json 文件

✨ 目录 ▷ 安装 varest 扩展▷ 开启 varest 扩展▷ 发送 get 请求▷ 发送 post 请求▷ 读取 json 文件 ▷ 安装 varest 扩展 打开 虚幻商城,搜索 varest 关键字进行检索, varest 是一个 api 调用插件,支持 http/https 请求,也支…

【成都活动邀请函】7月6 | PowerData 数字经济-“成都“开源行!

【成都活动邀请函】7月6 | PowerData 数字经济-"成都"开源行! 活动介绍活动信息线上直播扫码报名往期活动回顾专注数据开源,推动大数据发展 活动介绍 九天开出一成都,万户千门入画图。 自古以来,成都便是国家发展的重要…

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 下载页 ->Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人…

爬坑之 [‘NODE_ENV‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。]

在package.json中配置如下: 执行npm run dev启动 报错: 实际上, NODE_ENVdevelopment webpack-dev-server 这条脚本会合并为两条命令执行, 分别为: NODE_EVNdevelopment webpack-dev-server 这种写法在cmd中是不被支持的 解决…

==和equals的区别(面试题)

和equals有什么区别 对于基本数据类型,比较的是值是否相等,对于引用类型则是比较的地址是否相等;对于equals来说,基本数据类型没有equals方法,对于引用类型equals比较的是引用对象是否相同 那针对以上结论&#xff0c…

LINUX系统编程:多线程互斥

目录 1.铺垫 2.线程锁接口的认识 静态锁分配 动态锁的分配 互斥量的销毁 互斥量加锁和解锁 3.加锁版抢票 4.互斥的底层实现 1.铺垫 先提一个小场景,有1000张票,现在有4个进程,这四个进程疯狂的去抢这1000张票,看看会发生什…

205.Mit6.S081-实验二 system calls

Lab2:system calls 在上一个实验室中,您使用系统调用编写了一些实用程序。在本实验室中,您将向xv6添加一些新的系统调用,这将帮助您了解它们是如何工作的,并使您了解xv6内核的一些内部结构。您将在以后的实验室中添加更多系统调用…

Spring Cloud Alibaba之负载均衡组件Ribbon

一、什么是负载均衡? (1)概念: 在基于微服务架构开发的系统里,为了能够提升系统应对高并发的能力,开发人员通常会把具有相同业务功能的模块同时部署到多台的服务器中,并把访问业务功能的请求均…

grpc学习golang版( 五、多proto文件示例 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件2.1 公共proto文件2.2 语音唤醒proto文…

简单多状态DP问题

这里写目录标题 什么是多状态DP解决多状态DP问题应该怎么做?关于多状态DP问题的几道题1.按摩师2.打家劫舍Ⅱ3.删除并获得点数4.粉刷房子5.买卖股票的最佳时期含手冷冻期 总结 什么是多状态DP 多状态动态规划(Multi-State Dynamic Programming, Multi-St…

Elasticsearch 第四期:搜索和过滤

序 2024年4月,小组计算建设标签平台,使用ES等工具建了一个demo,由于领导变动关系,项目基本夭折。其实这两年也陆陆续续接触和使用过ES,两年前也看过ES的官网,当时刚毕业半年多,由于历史局限性导…